Skip to content

Commit a02b0fc

Browse files
committed
PowerVS: Fix CAPI to use service instance
We should be passing in the ServiceInstance structure which handles both pre-existing and CAPI created versions. Also we did not properly get the service instance GUID.
1 parent ca71358 commit a02b0fc

File tree

6 files changed

+1107
-943
lines changed

6 files changed

+1107
-943
lines changed

data/data/cluster-api/ibmcloud-infrastructure-components.yaml

Lines changed: 967 additions & 889 deletions
Large diffs are not rendered by default.

pkg/asset/installconfig/powervs/client.go

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type API interface {
6767
// Service Instance
6868
ListServiceInstances(ctx context.Context) ([]string, error)
6969
ServiceInstanceGUIDToName(ctx context.Context, id string) (string, error)
70+
ServiceInstanceNameToGUID(ctx context.Context, name string) (string, error)
7071

7172
// Security Group
7273
ListSecurityGroupRules(ctx context.Context, securityGroupID string) (*vpcv1.SecurityGroupRuleCollection, error)
@@ -89,8 +90,10 @@ type Client struct {
8990

9091
// cisServiceID is the Cloud Internet Services' catalog service ID.
9192
const (
92-
cisServiceID = "75874a60-cb12-11e7-948e-37ac098eb1b9"
93-
dnsServiceID = "b4ed8a30-936f-11e9-b289-1d079699cbe5"
93+
cisServiceID = "75874a60-cb12-11e7-948e-37ac098eb1b9"
94+
dnsServiceID = "b4ed8a30-936f-11e9-b289-1d079699cbe5"
95+
serviceInstanceType = "service_instance"
96+
compositeInstanceType = "composite_instance"
9497
)
9598

9699
// DNSZoneResponse represents a DNS zone response.
@@ -743,7 +746,7 @@ func (c *Client) ListServiceInstances(ctx context.Context) ([]string, error) {
743746
continue
744747
}
745748

746-
if resourceInstance.Type != nil && (*resourceInstance.Type == "service_instance" || *resourceInstance.Type == "composite_instance") {
749+
if resourceInstance.Type != nil && (*resourceInstance.Type == serviceInstanceType || *resourceInstance.Type == compositeInstanceType) {
747750
serviceInstances = append(serviceInstances, fmt.Sprintf("%s %s", *resource.Name, *resource.GUID))
748751
}
749752
}
@@ -819,7 +822,7 @@ func (c *Client) ServiceInstanceGUIDToName(ctx context.Context, id string) (stri
819822
continue
820823
}
821824

822-
if resourceInstance.Type != nil && (*resourceInstance.Type == "service_instance" || *resourceInstance.Type == "composite_instance") {
825+
if resourceInstance.Type != nil && (*resourceInstance.Type == serviceInstanceType || *resourceInstance.Type == compositeInstanceType) {
823826
if resourceInstance.GUID != nil && *resourceInstance.GUID == id {
824827
if resourceInstance.Name == nil {
825828
return "", nil
@@ -846,6 +849,87 @@ func (c *Client) ServiceInstanceGUIDToName(ctx context.Context, id string) (stri
846849
return "", nil
847850
}
848851

852+
// ServiceInstanceNameToGUID returns the name of the matching service instance GUID which was passed in.
853+
func (c *Client) ServiceInstanceNameToGUID(ctx context.Context, name string) (string, error) {
854+
var (
855+
options *resourcecontrollerv2.ListResourceInstancesOptions
856+
resources *resourcecontrollerv2.ResourceInstancesList
857+
err error
858+
perPage int64 = 10
859+
moreData = true
860+
nextURL *string
861+
groupID = c.BXCli.PowerVSResourceGroup
862+
)
863+
864+
// If the user passes in a human readable group id, then we need to convert it to a UUID
865+
listGroupOptions := c.managementAPI.NewListResourceGroupsOptions()
866+
listGroupOptions.AccountID = &c.BXCli.User.Account
867+
groups, _, err := c.managementAPI.ListResourceGroupsWithContext(ctx, listGroupOptions)
868+
if err != nil {
869+
return "", fmt.Errorf("failed to list resource groups: %w", err)
870+
}
871+
for _, group := range groups.Resources {
872+
if *group.Name == groupID {
873+
groupID = *group.ID
874+
}
875+
}
876+
877+
options = c.controllerAPI.NewListResourceInstancesOptions()
878+
options.SetResourceGroupID(groupID)
879+
// resource ID for Power Systems Virtual Server in the Global catalog
880+
options.SetResourceID(powerIAASResourceID)
881+
options.SetLimit(perPage)
882+
883+
for moreData {
884+
resources, _, err = c.controllerAPI.ListResourceInstancesWithContext(ctx, options)
885+
if err != nil {
886+
return "", fmt.Errorf("failed to list resource instances: %w", err)
887+
}
888+
889+
for _, resource := range resources.Resources {
890+
var (
891+
getResourceOptions *resourcecontrollerv2.GetResourceInstanceOptions
892+
resourceInstance *resourcecontrollerv2.ResourceInstance
893+
response *core.DetailedResponse
894+
)
895+
896+
getResourceOptions = c.controllerAPI.NewGetResourceInstanceOptions(*resource.ID)
897+
898+
resourceInstance, response, err = c.controllerAPI.GetResourceInstance(getResourceOptions)
899+
if err != nil {
900+
return "", fmt.Errorf("failed to get instance: %w", err)
901+
}
902+
if response != nil && response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusInternalServerError {
903+
continue
904+
}
905+
906+
if resourceInstance.Type != nil && (*resourceInstance.Type == serviceInstanceType || *resourceInstance.Type == compositeInstanceType) {
907+
if resourceInstance.Name != nil && *resourceInstance.Name == name {
908+
if resourceInstance.GUID == nil {
909+
return "", nil
910+
}
911+
return *resourceInstance.GUID, nil
912+
}
913+
}
914+
}
915+
916+
// Based on: https://cloud.ibm.com/apidocs/resource-controller/resource-controller?code=go#list-resource-instances
917+
nextURL, err = core.GetQueryParam(resources.NextURL, "start")
918+
if err != nil {
919+
return "", fmt.Errorf("failed to GetQueryParam on start: %w", err)
920+
}
921+
if nextURL == nil {
922+
options.SetStart("")
923+
} else {
924+
options.SetStart(*nextURL)
925+
}
926+
927+
moreData = *resources.RowsCount == perPage
928+
}
929+
930+
return "", nil
931+
}
932+
849933
// GetDatacenterCapabilities retrieves the capabilities of the specified datacenter.
850934
func (c *Client) GetDatacenterCapabilities(ctx context.Context, region string) (map[string]bool, error) {
851935
var err error

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

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

pkg/asset/machines/powervs/powervsmachines.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func GenerateMachines(clusterID string, ic *types.InstallConfig, pool *types.Mac
4242
image = fmt.Sprintf("rhcos-%s", clusterID)
4343

4444
if ic.PowerVS.ServiceInstanceGUID == "" {
45-
serviceName := fmt.Sprintf("%s-iaas", clusterID)
45+
serviceName := fmt.Sprintf("%s-power-iaas", clusterID)
4646

4747
service = capibm.IBMPowerVSResourceReference{
4848
Name: &serviceName,

pkg/asset/manifests/powervs/cluster.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID
5050
network = fmt.Sprintf("%s-network", clusterID.InfraID)
5151

5252
if installConfig.Config.PowerVS.ServiceInstanceGUID == "" {
53-
serviceName := fmt.Sprintf("%s-iaas", clusterID.InfraID)
53+
serviceName := fmt.Sprintf("%s-power-iaas", clusterID.InfraID)
5454

5555
service = capibm.IBMPowerVSResourceReference{
5656
Name: &serviceName,
@@ -177,11 +177,11 @@ func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID
177177
Namespace: capiutils.Namespace,
178178
},
179179
Spec: capibm.IBMPowerVSImageSpec{
180-
ClusterName: clusterID.InfraID,
181-
ServiceInstanceID: installConfig.Config.PowerVS.ServiceInstanceGUID,
182-
Bucket: &bucket,
183-
Object: &object,
184-
Region: &vpcRegion,
180+
ClusterName: clusterID.InfraID,
181+
ServiceInstance: &service,
182+
Bucket: &bucket,
183+
Object: &object,
184+
Region: &vpcRegion,
185185
},
186186
}
187187

pkg/infrastructure/powervs/clusterapi/powervs.go

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ func (p Provider) PostProvision(ctx context.Context, in clusterapi.PostProvision
294294
refServiceInstance *capibm.IBMPowerVSResourceReference
295295
sshKeyName string
296296
err error
297+
instanceID *string
298+
fieldType string
297299
)
298300

299301
// SAD: client in the Metadata struct is lowercase and therefore private
@@ -332,60 +334,45 @@ func (p Provider) PostProvision(ctx context.Context, in clusterapi.PostProvision
332334
logrus.Debugf("PostProvision: CreateSSHKey: si id = %s, key = %s",
333335
*refServiceInstance.ID,
334336
in.InstallConfig.Config.SSHKey)
335-
336-
backoff := wait.Backoff{
337-
Duration: 15 * time.Second,
338-
Factor: 1.1,
339-
Cap: leftInContext(ctx),
340-
Steps: math.MaxInt32}
341-
err = wait.ExponentialBackoffWithContext(ctx, backoff, func(context.Context) (bool, error) {
342-
err2 := client.CreateSSHKey(ctx,
343-
*refServiceInstance.ID,
344-
*powerVSMachine.Status.Zone,
345-
sshKeyName,
346-
in.InstallConfig.Config.SSHKey)
347-
if err2 == nil {
348-
return true, nil
349-
}
350-
return false, err2
351-
})
352-
if err != nil {
353-
return fmt.Errorf("failed to add SSH key for the workers(ID): %w", err)
354-
}
337+
instanceID = refServiceInstance.ID
338+
fieldType = "ID"
355339
case refServiceInstance.Name != nil:
356340
logrus.Debugf("PostProvision: CreateSSHKey: si name = %s, key = %s",
357341
*refServiceInstance.Name,
358342
in.InstallConfig.Config.SSHKey)
359-
360-
vpc, err := client.GetVPCByName(ctx, *refServiceInstance.Name)
343+
guid, err := client.ServiceInstanceNameToGUID(ctx, *refServiceInstance.Name)
361344
if err != nil {
362-
return fmt.Errorf("failed to find id for VPC name %s: %w",
345+
return fmt.Errorf("failed to find id for ServiceInstance name %s: %w",
363346
*refServiceInstance.Name,
364347
err)
365348
}
366-
367-
backoff := wait.Backoff{
368-
Duration: 15 * time.Second,
369-
Factor: 1.1,
370-
Cap: leftInContext(ctx),
371-
Steps: math.MaxInt32}
372-
err = wait.ExponentialBackoffWithContext(ctx, backoff, func(context.Context) (bool, error) {
373-
err2 := client.CreateSSHKey(ctx,
374-
*vpc.ID,
375-
*powerVSMachine.Status.Zone,
376-
sshKeyName,
377-
in.InstallConfig.Config.SSHKey)
378-
if err2 == nil {
379-
return true, nil
380-
}
381-
return false, err2
382-
})
383-
if err != nil {
384-
return fmt.Errorf("failed to add SSH key for the workers(Name): %w", err)
385-
}
349+
logrus.Debugf("PostProvision: CreateSSHKey: guid = %s", guid)
350+
instanceID = ptr.To(guid)
351+
fieldType = "Name"
386352
default:
387353
return fmt.Errorf("could not handle powerVSMachine.Spec.ServiceInstance")
388354
}
389355

356+
backoff := wait.Backoff{
357+
Duration: 15 * time.Second,
358+
Factor: 1.1,
359+
Cap: leftInContext(ctx),
360+
Steps: math.MaxInt32,
361+
}
362+
err = wait.ExponentialBackoffWithContext(ctx, backoff, func(context.Context) (bool, error) {
363+
err2 := client.CreateSSHKey(ctx,
364+
*instanceID,
365+
*powerVSMachine.Status.Zone,
366+
sshKeyName,
367+
in.InstallConfig.Config.SSHKey)
368+
if err2 == nil {
369+
return true, nil
370+
}
371+
return false, err2
372+
})
373+
if err != nil {
374+
return fmt.Errorf("failed to add SSH key for the workers(%s): %w", fieldType, err)
375+
}
376+
390377
return nil
391378
}

0 commit comments

Comments
 (0)