Skip to content

Commit 9557b51

Browse files
Merge pull request #8243 from mjturek/custom-resolver
MULTIARCH-4550: Power VS: Use a custom resolver when publish strategy is Internal
2 parents 6027805 + 4dd009b commit 9557b51

File tree

4 files changed

+135
-10
lines changed

4 files changed

+135
-10
lines changed

pkg/asset/installconfig/powervs/client.go

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ type API interface {
3939
GetDNSZoneIDByName(ctx context.Context, name string, publish types.PublishingStrategy) (string, error)
4040
GetDNSZones(ctx context.Context, publish types.PublishingStrategy) ([]DNSZoneResponse, error)
4141
GetDNSInstancePermittedNetworks(ctx context.Context, dnsID string, dnsZone string) ([]string, error)
42+
GetDNSCustomResolverIP(ctx context.Context, dnsID string, vpcID string) (string, error)
4243
CreateDNSRecord(ctx context.Context, crnstr string, baseDomain string, hostname string, cname string) error
4344

4445
// VPC
4546
GetVPCByName(ctx context.Context, vpcName string) (*vpcv1.VPC, error)
4647
GetPublicGatewayByVPC(ctx context.Context, vpcName string) (*vpcv1.PublicGateway, error)
4748
SetVPCServiceURLForRegion(ctx context.Context, region string) error
4849
GetVPCs(ctx context.Context, region string) ([]vpcv1.VPC, error)
50+
GetVPCSubnets(ctx context.Context, vpcID string) ([]vpcv1.Subnet, error)
4951

5052
// TG
5153
GetTGConnectionVPC(ctx context.Context, gatewayID string, vpcSubnetID string) (string, error)
@@ -253,7 +255,6 @@ func (c *Client) GetDNSRecordsByName(ctx context.Context, crnstr string, zoneID
253255

254256
// GetInstanceCRNByName finds the CRN of the instance with the specified name.
255257
func (c *Client) GetInstanceCRNByName(ctx context.Context, name string, publish types.PublishingStrategy) (string, error) {
256-
257258
zones, err := c.GetDNSZones(ctx, publish)
258259
if err != nil {
259260
return "", err
@@ -268,9 +269,33 @@ func (c *Client) GetInstanceCRNByName(ctx context.Context, name string, publish
268269
return "", fmt.Errorf("DNS zone %q not found", name)
269270
}
270271

272+
// GetDNSCustomResolverIP gets the DNS Server IP of a custom resolver associated with the specified VPC subnet in the specified DNS zone.
273+
func (c *Client) GetDNSCustomResolverIP(ctx context.Context, dnsID string, vpcID string) (string, error) {
274+
listCustomResolversOptions := c.dnsServicesAPI.NewListCustomResolversOptions(dnsID)
275+
customResolvers, _, err := c.dnsServicesAPI.ListCustomResolversWithContext(ctx, listCustomResolversOptions)
276+
if err != nil {
277+
return "", err
278+
}
279+
280+
subnets, err := c.GetVPCSubnets(ctx, vpcID)
281+
if err != nil {
282+
return "", err
283+
}
284+
285+
for _, customResolver := range customResolvers.CustomResolvers {
286+
for _, location := range customResolver.Locations {
287+
for _, subnet := range subnets {
288+
if *subnet.CRN == *location.SubnetCrn {
289+
return *location.DnsServerIp, nil
290+
}
291+
}
292+
}
293+
}
294+
return "", fmt.Errorf("DNS server IP of custom resolver for %q not found", dnsID)
295+
}
296+
271297
// GetDNSZoneIDByName gets the CIS zone ID from its domain name.
272298
func (c *Client) GetDNSZoneIDByName(ctx context.Context, name string, publish types.PublishingStrategy) (string, error) {
273-
274299
zones, err := c.GetDNSZones(ctx, publish)
275300
if err != nil {
276301
return "", err
@@ -372,7 +397,7 @@ func (c *Client) GetDNSZones(ctx context.Context, publish types.PublishingStrate
372397
return allZones, nil
373398
}
374399

375-
// GetDNSInstancePermittedNetworks gets the permitted VPC networks for a DNS Services instance
400+
// GetDNSInstancePermittedNetworks gets the permitted VPC networks for a DNS Services instance.
376401
func (c *Client) GetDNSInstancePermittedNetworks(ctx context.Context, dnsID string, dnsZone string) ([]string, error) {
377402
_, cancel := context.WithTimeout(ctx, 1*time.Minute)
378403
defer cancel()
@@ -510,6 +535,18 @@ func (c *Client) GetPublicGatewayByVPC(ctx context.Context, vpcName string) (*vp
510535
return nil, nil
511536
}
512537

538+
// GetVPCSubnets retrieves all subnets in the given VPC.
539+
func (c *Client) GetVPCSubnets(ctx context.Context, vpcID string) ([]vpcv1.Subnet, error) {
540+
listSubnetsOptions := c.vpcAPI.NewListSubnetsOptions()
541+
listSubnetsOptions.VPCID = &vpcID
542+
subnets, _, err := c.vpcAPI.ListSubnetsWithContext(ctx, listSubnetsOptions)
543+
if err != nil {
544+
return nil, err
545+
}
546+
547+
return subnets.Subnets, nil
548+
}
549+
513550
// GetSubnetByName gets a VPC Subnet by its name and region.
514551
func (c *Client) GetSubnetByName(ctx context.Context, subnetName string, region string) (*vpcv1.Subnet, error) {
515552
_, cancel := context.WithTimeout(ctx, 1*time.Minute)

pkg/asset/installconfig/powervs/metadata.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"sync"
77

88
"github.com/IBM-Cloud/bluemix-go/crn"
9+
"github.com/IBM/vpc-go-sdk/vpcv1"
910

1011
"github.com/openshift/installer/pkg/types"
1112
)
@@ -240,3 +241,43 @@ func (m *Metadata) IsVPCPermittedNetwork(ctx context.Context, vpcName string, ba
240241

241242
return false, nil
242243
}
244+
245+
// GetSubnetID gets the ID of a VPC subnet by name and region.
246+
func (m *Metadata) GetSubnetID(ctx context.Context, subnetName string, vpcRegion string) (string, error) {
247+
subnet, err := m.client.GetSubnetByName(ctx, subnetName, vpcRegion)
248+
if err != nil {
249+
return "", err
250+
}
251+
return *subnet.ID, err
252+
}
253+
254+
// GetVPCSubnets gets a list of subnets in a VPC.
255+
func (m *Metadata) GetVPCSubnets(ctx context.Context, vpcName string) ([]vpcv1.Subnet, error) {
256+
vpc, err := m.client.GetVPCByName(ctx, vpcName)
257+
if err != nil {
258+
return nil, err
259+
}
260+
subnets, err := m.client.GetVPCSubnets(ctx, *vpc.ID)
261+
if err != nil {
262+
return nil, fmt.Errorf("failed to get VPC subnets: %w", err)
263+
}
264+
return subnets, err
265+
}
266+
267+
// GetDNSServerIP gets the IP of a custom resolver for DNS use.
268+
func (m *Metadata) GetDNSServerIP(ctx context.Context, vpcName string) (string, error) {
269+
vpc, err := m.client.GetVPCByName(ctx, vpcName)
270+
if err != nil {
271+
return "", err
272+
}
273+
274+
dnsCRN, err := crn.Parse(m.dnsInstanceCRN)
275+
if err != nil {
276+
return "", fmt.Errorf("failed to parse DNSInstanceCRN: %w", err)
277+
}
278+
dnsServerIP, err := m.client.GetDNSCustomResolverIP(ctx, dnsCRN.ServiceInstance, *vpc.ID)
279+
if err != nil {
280+
return "", err
281+
}
282+
return dnsServerIP, nil
283+
}

pkg/asset/installconfig/powervs/mock/powervsclient_generated.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/asset/manifests/powervs/cluster.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package powervs
22

33
import (
4+
"context"
45
"fmt"
56

67
"github.com/sirupsen/logrus"
@@ -12,6 +13,7 @@ import (
1213
"github.com/openshift/installer/pkg/asset"
1314
"github.com/openshift/installer/pkg/asset/installconfig"
1415
"github.com/openshift/installer/pkg/asset/manifests/capiutils"
16+
"github.com/openshift/installer/pkg/types"
1517
powervstypes "github.com/openshift/installer/pkg/types/powervs"
1618
)
1719

@@ -154,15 +156,30 @@ func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID
154156
},
155157
}
156158

157-
// Avoid empty manifest elements
158-
logrus.Debugf("GenerateClusterAssets: len(VPCSubnets) = %d", len(installConfig.Config.Platform.PowerVS.VPCSubnets))
159-
if len(installConfig.Config.Platform.PowerVS.VPCSubnets) > 0 {
160-
powerVSCluster.Spec.VPCSubnets = make([]capibm.Subnet, 0)
161-
for i := range installConfig.Config.Platform.PowerVS.VPCSubnets {
162-
// We cannot get the string in the loop and add it as it appears duplicated in the generated file
159+
// Use a custom resolver if using an Internal publishing strategy
160+
if installConfig.Config.Publish == types.InternalPublishingStrategy {
161+
dnsServerIP, err := installConfig.PowerVS.GetDNSServerIP(context.TODO(), installConfig.Config.PowerVS.VPCName)
162+
if err != nil {
163+
return nil, fmt.Errorf("unable to find a DNS server for specified VPC: %s %w", installConfig.Config.PowerVS.VPCName, err)
164+
}
165+
166+
powerVSCluster.Spec.DHCPServer = &capibm.DHCPServer{
167+
DNSServer: &dnsServerIP,
168+
}
169+
}
170+
171+
// If a VPC was specified, pass all subnets in it to cluster API
172+
if installConfig.Config.Platform.PowerVS.VPCName != "" {
173+
logrus.Debugf("GenerateClusterAssets: VPCName = %s", installConfig.Config.Platform.PowerVS.VPCName)
174+
subnets, err := installConfig.PowerVS.GetVPCSubnets(context.TODO(), vpcName)
175+
if err != nil {
176+
return nil, fmt.Errorf("error getting subnets in specified VPC: %s %w", installConfig.Config.PowerVS.VPCName, err)
177+
}
178+
for _, subnet := range subnets {
163179
powerVSCluster.Spec.VPCSubnets = append(powerVSCluster.Spec.VPCSubnets,
164180
capibm.Subnet{
165-
ID: &installConfig.Config.Platform.PowerVS.VPCSubnets[i],
181+
ID: subnet.ID,
182+
Name: subnet.Name,
166183
})
167184
}
168185
logrus.Debugf("GenerateClusterAssets: subnets = %+v", powerVSCluster.Spec.VPCSubnets)

0 commit comments

Comments
 (0)