From 22d4a3868b6485760a481dfdbcecbf37f740c482 Mon Sep 17 00:00:00 2001 From: Amulyam24 Date: Wed, 28 Aug 2024 17:05:12 +0530 Subject: [PATCH] Refactor reconcilation of resources --- api/v1beta2/ibmpowervscluster_webhook.go | 19 ++- cloud/scope/powervs_cluster.go | 167 +++++++++++--------- controllers/ibmpowervscluster_controller.go | 6 +- 3 files changed, 109 insertions(+), 83 deletions(-) diff --git a/api/v1beta2/ibmpowervscluster_webhook.go b/api/v1beta2/ibmpowervscluster_webhook.go index 52ce0086c..744dc4a94 100644 --- a/api/v1beta2/ibmpowervscluster_webhook.go +++ b/api/v1beta2/ibmpowervscluster_webhook.go @@ -105,10 +105,12 @@ func (r *IBMPowerVSCluster) validateIBMPowerVSClusterNetwork() *field.Error { func (r *IBMPowerVSCluster) validateIBMPowerVSClusterLoadBalancerNames() (allErrs field.ErrorList) { found := make(map[string]bool) for i, loadbalancer := range r.Spec.LoadBalancers { - if found[loadbalancer.Name] { - allErrs = append(allErrs, field.Duplicate(field.NewPath("spec", fmt.Sprintf("loadbalancers[%d]", i)), map[string]interface{}{"Name": loadbalancer.Name})) + if loadbalancer.Name != "" { + if found[loadbalancer.Name] { + allErrs = append(allErrs, field.Duplicate(field.NewPath("spec", fmt.Sprintf("loadbalancers[%d]", i)), map[string]interface{}{"Name": loadbalancer.Name})) + } + found[loadbalancer.Name] = true } - found[loadbalancer.Name] = true } return allErrs @@ -117,10 +119,12 @@ func (r *IBMPowerVSCluster) validateIBMPowerVSClusterLoadBalancerNames() (allErr func (r *IBMPowerVSCluster) validateIBMPowerVSClusterVPCSubnetNames() (allErrs field.ErrorList) { found := make(map[string]bool) for i, subnet := range r.Spec.VPCSubnets { - if found[*subnet.Name] { - allErrs = append(allErrs, field.Duplicate(field.NewPath("spec", fmt.Sprintf("vpcSubnets[%d]", i)), map[string]interface{}{"Name": *subnet.Name})) + if subnet.Name != nil { + if found[*subnet.Name] { + allErrs = append(allErrs, field.Duplicate(field.NewPath("spec", fmt.Sprintf("vpcSubnets[%d]", i)), map[string]interface{}{"Name": *subnet.Name})) + } + found[*subnet.Name] = true } - found[*subnet.Name] = true } return allErrs @@ -130,6 +134,9 @@ func (r *IBMPowerVSCluster) validateIBMPowerVSClusterTransitGateway() *field.Err if r.Spec.Zone == nil && r.Spec.VPC == nil { return nil } + if r.Spec.TransitGateway == nil { + return nil + } if _, globalRouting, _ := genUtil.GetTransitGatewayLocationAndRouting(r.Spec.Zone, r.Spec.VPC.Region); r.Spec.TransitGateway.GlobalRouting != nil && !*r.Spec.TransitGateway.GlobalRouting && globalRouting != nil && *globalRouting { return field.Invalid(field.NewPath("spec.transitGateway.globalRouting"), r.Spec.TransitGateway.GlobalRouting, "global routing is required since PowerVS and VPC region are from different region") } diff --git a/cloud/scope/powervs_cluster.go b/cloud/scope/powervs_cluster.go index a6d033c9b..cd6e3b83f 100644 --- a/cloud/scope/powervs_cluster.go +++ b/cloud/scope/powervs_cluster.go @@ -384,14 +384,8 @@ func (s *PowerVSClusterScope) ServiceInstance() *infrav1beta2.IBMPowerVSResource return s.IBMPowerVSCluster.Spec.ServiceInstance } -// GetServiceInstanceID get the service instance id. +// GetServiceInstanceID returns service instance id set in status field of IBMPowerVSCluster object. If it doesn't exist, returns empty string. func (s *PowerVSClusterScope) GetServiceInstanceID() string { - if s.IBMPowerVSCluster.Spec.ServiceInstanceID != "" { - return s.IBMPowerVSCluster.Spec.ServiceInstanceID - } - if s.IBMPowerVSCluster.Spec.ServiceInstance != nil && s.IBMPowerVSCluster.Spec.ServiceInstance.ID != nil { - return *s.IBMPowerVSCluster.Spec.ServiceInstance.ID - } if s.IBMPowerVSCluster.Status.ServiceInstance != nil && s.IBMPowerVSCluster.Status.ServiceInstance.ID != nil { return *s.IBMPowerVSCluster.Status.ServiceInstance.ID } @@ -470,11 +464,8 @@ func (s *PowerVSClusterScope) Network() *infrav1beta2.IBMPowerVSResourceReferenc return &s.IBMPowerVSCluster.Spec.Network } -// GetDHCPServerID returns the DHCP id from spec or status of IBMPowerVSCluster object. +// GetDHCPServerID returns the DHCP id from status of IBMPowerVSCluster object. If it doesn't exist, returns nil. func (s *PowerVSClusterScope) GetDHCPServerID() *string { - if s.IBMPowerVSCluster.Spec.DHCPServer != nil && s.IBMPowerVSCluster.Spec.DHCPServer.ID != nil { - return s.IBMPowerVSCluster.Spec.DHCPServer.ID - } if s.IBMPowerVSCluster.Status.DHCPServer != nil { return s.IBMPowerVSCluster.Status.DHCPServer.ID } @@ -491,11 +482,8 @@ func (s *PowerVSClusterScope) VPC() *infrav1beta2.VPCResourceReference { return s.IBMPowerVSCluster.Spec.VPC } -// GetVPCID returns the VPC id. +// GetVPCID returns the VPC id set in status field of IBMPowerVSCluster object. If it doesn't exist, returns nil. func (s *PowerVSClusterScope) GetVPCID() *string { - if s.IBMPowerVSCluster.Spec.VPC != nil && s.IBMPowerVSCluster.Spec.VPC.ID != nil { - return s.IBMPowerVSCluster.Spec.VPC.ID - } if s.IBMPowerVSCluster.Status.VPC != nil { return s.IBMPowerVSCluster.Status.VPC.ID } @@ -516,15 +504,6 @@ func (s *PowerVSClusterScope) GetVPCSubnetID(subnetName string) *string { // GetVPCSubnetIDs returns all the VPC subnet ids. func (s *PowerVSClusterScope) GetVPCSubnetIDs() []*string { subnets := []*string{} - // use the vpc subnet id set by user. - for _, subnet := range s.IBMPowerVSCluster.Spec.VPCSubnets { - if subnet.ID != nil { - subnets = append(subnets, subnet.ID) - } - } - if len(subnets) != 0 { - return subnets - } if s.IBMPowerVSCluster.Status.VPCSubnet == nil { return nil } @@ -534,8 +513,8 @@ func (s *PowerVSClusterScope) GetVPCSubnetIDs() []*string { return subnets } -// SetVPCSubnetID set the VPC subnet id. -func (s *PowerVSClusterScope) SetVPCSubnetID(name string, resource infrav1beta2.ResourceReference) { +// SetVPCSubnetStatus set the VPC subnet id. +func (s *PowerVSClusterScope) SetVPCSubnetStatus(name string, resource infrav1beta2.ResourceReference) { s.V(3).Info("Setting status", "name", name, "resource", resource) if s.IBMPowerVSCluster.Status.VPCSubnet == nil { s.IBMPowerVSCluster.Status.VPCSubnet = make(map[string]infrav1beta2.ResourceReference) @@ -572,8 +551,8 @@ func (s *PowerVSClusterScope) GetVPCSecurityGroupByID(securityGroupID string) (* return nil, nil, nil } -// SetVPCSecurityGroup set the VPC security group id. -func (s *PowerVSClusterScope) SetVPCSecurityGroup(name string, resource infrav1beta2.VPCSecurityGroupStatus) { +// SetVPCSecurityGroupStatus set the VPC security group id. +func (s *PowerVSClusterScope) SetVPCSecurityGroupStatus(name string, resource infrav1beta2.VPCSecurityGroupStatus) { s.V(3).Info("Setting VPC security group status", "name", name, "resource", resource) if s.IBMPowerVSCluster.Status.VPCSecurityGroups == nil { s.IBMPowerVSCluster.Status.VPCSecurityGroups = make(map[string]infrav1beta2.VPCSecurityGroupStatus) @@ -600,20 +579,29 @@ func (s *PowerVSClusterScope) GetTransitGatewayID() *string { } // PublicLoadBalancer returns the cluster public loadBalancer information. -func (s *PowerVSClusterScope) PublicLoadBalancer() *infrav1beta2.VPCLoadBalancerSpec { +func (s *PowerVSClusterScope) PublicLoadBalancer() (*infrav1beta2.VPCLoadBalancerSpec, error) { // if the user did not specify any loadbalancer then return the public loadbalancer created by the controller. if len(s.IBMPowerVSCluster.Spec.LoadBalancers) == 0 { return &infrav1beta2.VPCLoadBalancerSpec{ Name: *s.GetServiceName(infrav1beta2.ResourceTypeLoadBalancer), Public: ptr.To(true), - } + }, nil } for _, lb := range s.IBMPowerVSCluster.Spec.LoadBalancers { + if lb.ID != nil && lb.Name == "" { + loadBalancer, _, err := s.IBMVPCClient.GetLoadBalancer(&vpcv1.GetLoadBalancerOptions{ + ID: lb.ID, + }) + if err != nil { + return nil, err + } + lb.Name = *loadBalancer.Name + } if lb.Public != nil && *lb.Public { - return &lb + return &lb, nil } } - return nil + return nil, nil } // SetLoadBalancerStatus set the loadBalancer id. @@ -663,7 +651,7 @@ func (s *PowerVSClusterScope) GetLoadBalancerHostName(name string) *string { return nil } -// GetResourceGroupID returns the resource group id if it present under spec or statue filed of IBMPowerVSCluster object +// GetResourceGroupID returns the resource group id if it present under spec or status filed of IBMPowerVSCluster object // or returns empty string. func (s *PowerVSClusterScope) GetResourceGroupID() string { if s.IBMPowerVSCluster.Spec.ResourceGroup != nil && s.IBMPowerVSCluster.Spec.ResourceGroup.ID != nil { @@ -716,7 +704,7 @@ func (s *PowerVSClusterScope) ReconcileResourceGroup() error { // ReconcilePowerVSServiceInstance reconciles Power VS service instance. func (s *PowerVSClusterScope) ReconcilePowerVSServiceInstance() (bool, error) { - // Verify if service instance id is set in spec or status field of IBMPowerVSCluster object. + // Verify if service instance id is set in status field of IBMPowerVSCluster object. serviceInstanceID := s.GetServiceInstanceID() if serviceInstanceID != "" { s.V(3).Info("PowerVS service instance ID is set, fetching details", "id", serviceInstanceID) @@ -745,6 +733,7 @@ func (s *PowerVSClusterScope) ReconcilePowerVSServiceInstance() (bool, error) { } // Set the status of IBMPowerVSCluster object with serviceInstanceID and ControllerCreated to false as PowerVS service instance is already exist in cloud. if serviceInstanceID != "" { + s.V(3).Info("Found PowerVS service instance in IBM Cloud", "id", serviceInstanceID) s.SetStatus(infrav1beta2.ResourceTypeServiceInstance, infrav1beta2.ResourceReference{ID: &serviceInstanceID, ControllerCreated: ptr.To(false)}) return requeue, nil } @@ -782,17 +771,38 @@ func (s *PowerVSClusterScope) checkServiceInstanceState(instance resourcecontrol return false, nil } -// checkServiceInstance checks PowerVS service instance exist in cloud. +// checkServiceInstance checks PowerVS service instance exist in cloud by ID or name. func (s *PowerVSClusterScope) isServiceInstanceExists() (string, bool, error) { s.V(3).Info("Checking for PowerVS service instance in IBM Cloud") - // Fetches service instance by name. - serviceInstance, err := s.getServiceInstance() + var ( + id string + err error + serviceInstance *resourcecontrollerv2.ResourceInstance + ) + + if s.IBMPowerVSCluster.Spec.ServiceInstanceID != "" { + id = s.IBMPowerVSCluster.Spec.ServiceInstanceID + } else if s.IBMPowerVSCluster.Spec.ServiceInstance != nil && s.IBMPowerVSCluster.Spec.ServiceInstance.ID != nil { + id = *s.IBMPowerVSCluster.Spec.ServiceInstance.ID + } + + if id != "" { + // Fetches service instance by ID. + serviceInstance, _, err = s.ResourceClient.GetResourceInstance(&resourcecontrollerv2.GetResourceInstanceOptions{ + ID: &id, + }) + } else { + // Fetches service instance by name. + serviceInstance, err = s.getServiceInstance() + } + if err != nil { s.Error(err, "failed to get PowerVS service instance") return "", false, err } + if serviceInstance == nil { - s.V(3).Info("PowerVS service instance with given name does not exist in IBM Cloud", "name", *s.GetServiceName(infrav1beta2.ResourceTypeServiceInstance)) + s.V(3).Info("PowerVS service instance with given ID or name does not exist in IBM Cloud") return "", false, nil } @@ -871,30 +881,14 @@ func (s *PowerVSClusterScope) ReconcileNetwork() (bool, error) { return false, nil } -// checkNetwork checks the network exist in cloud. +// checkNetwork checks if network exists in cloud with given name or ID mentioned in spec. func (s *PowerVSClusterScope) checkNetwork() (*string, error) { - // get network from cloud. s.V(3).Info("Checking if PowerVS network exists in IBM Cloud") - networkID, err := s.getNetwork() - if err != nil { - s.Error(err, "failed to get PowerVS network") - return nil, err - } - if networkID == nil { - s.V(3).Info("Unable to find PowerVS network in IBM Cloud", "network", s.IBMPowerVSCluster.Spec.Network) - return nil, nil - } - return networkID, nil -} - -func (s *PowerVSClusterScope) getNetwork() (*string, error) { - // fetch the network associated with network id if s.IBMPowerVSCluster.Spec.Network.ID != nil { network, err := s.IBMPowerVSClient.GetNetworkByID(*s.IBMPowerVSCluster.Spec.Network.ID) if err != nil { return nil, err } - s.V(3).Info("Found the PowerVS network", "id", network.NetworkID) return network.NetworkID, nil } @@ -912,20 +906,16 @@ func (s *PowerVSClusterScope) getNetwork() (*string, error) { if err != nil { return nil, err } - if network == nil { + if network == nil && network.NetworkID == nil { + s.V(3).Info("Unable to find PowerVS network in IBM Cloud", "network", s.IBMPowerVSCluster.Spec.Network) return nil, nil } return network.NetworkID, nil - //TODO: Support regular expression } // isDHCPServerActive checks if the DHCP server status is active. func (s *PowerVSClusterScope) isDHCPServerActive() (bool, error) { - dhcpID := *s.GetDHCPServerID() - if dhcpID == "" { - return false, fmt.Errorf("DHCP ID is empty") - } - dhcpServer, err := s.IBMPowerVSClient.GetDHCPServer(dhcpID) + dhcpServer, err := s.IBMPowerVSClient.GetDHCPServer(*s.GetDHCPServerID()) if err != nil { return false, err } @@ -1021,6 +1011,7 @@ func (s *PowerVSClusterScope) ReconcileVPC() (bool, error) { return false, err } if id != "" { + s.V(3).Info("VPC found in IBM Cloud", "id", id) s.SetStatus(infrav1beta2.ResourceTypeVPC, infrav1beta2.ResourceReference{ID: &id, ControllerCreated: ptr.To(false)}) return false, nil } @@ -1040,7 +1031,16 @@ func (s *PowerVSClusterScope) ReconcileVPC() (bool, error) { // checkVPC checks VPC exist in cloud. func (s *PowerVSClusterScope) checkVPC() (string, error) { - vpcDetails, err := s.getVPCByName() + var err error + var vpcDetails *vpcv1.VPC + if s.IBMPowerVSCluster.Spec.VPC != nil && s.IBMPowerVSCluster.Spec.VPC.ID != nil { + vpcDetails, _, err = s.IBMVPCClient.GetVPC(&vpcv1.GetVPCOptions{ + ID: s.IBMPowerVSCluster.Spec.VPC.ID, + }) + } else { + vpcDetails, err = s.getVPCByName() + } + if err != nil { s.Error(err, "failed to get VPC") return "", err @@ -1117,7 +1117,7 @@ func (s *PowerVSClusterScope) ReconcileVPCSubnets() (bool, error) { } } for index, subnet := range s.IBMPowerVSCluster.Spec.VPCSubnets { - if subnet.Name == nil { + if subnet.ID == nil && subnet.Name == nil { subnet.Name = ptr.To(fmt.Sprintf("%s-%d", *s.GetServiceName(infrav1beta2.ResourceTypeSubnet), index)) } subnets = append(subnets, subnet) @@ -1130,6 +1130,7 @@ func (s *PowerVSClusterScope) ReconcileVPCSubnets() (bool, error) { } else { subnetID = s.GetVPCSubnetID(*subnet.Name) } + if subnetID != nil { s.V(3).Info("VPC subnet ID is set, fetching details", "id", *subnetID) subnetDetails, _, err := s.IBMVPCClient.GetSubnet(&vpcv1.GetSubnetOptions{ @@ -1142,6 +1143,7 @@ func (s *PowerVSClusterScope) ReconcileVPCSubnets() (bool, error) { return false, fmt.Errorf("failed to get VPC subnet with ID %s", *subnetID) } // check for next subnet + s.SetVPCSubnetStatus(*subnetDetails.Name, infrav1beta2.ResourceReference{ID: subnetDetails.ID}) continue } @@ -1153,7 +1155,7 @@ func (s *PowerVSClusterScope) ReconcileVPCSubnets() (bool, error) { } if vpcSubnetID != "" { s.V(3).Info("Found VPC subnet in IBM Cloud", "id", vpcSubnetID) - s.SetVPCSubnetID(*subnet.Name, infrav1beta2.ResourceReference{ID: &vpcSubnetID, ControllerCreated: ptr.To(false)}) + s.SetVPCSubnetStatus(*subnet.Name, infrav1beta2.ResourceReference{ID: &vpcSubnetID, ControllerCreated: ptr.To(false)}) // check for next subnet continue } @@ -1165,13 +1167,13 @@ func (s *PowerVSClusterScope) ReconcileVPCSubnets() (bool, error) { return false, err } s.Info("Created VPC subnet", "id", subnetID) - s.SetVPCSubnetID(*subnet.Name, infrav1beta2.ResourceReference{ID: subnetID, ControllerCreated: ptr.To(true)}) + s.SetVPCSubnetStatus(*subnet.Name, infrav1beta2.ResourceReference{ID: subnetID, ControllerCreated: ptr.To(true)}) return true, nil } return false, nil } -// checkVPCSubnet checks VPC subnet exist in cloud. +// checkVPCSubnet checks if VPC subnet by the given name exists in cloud. func (s *PowerVSClusterScope) checkVPCSubnet(subnetName string) (string, error) { vpcSubnet, err := s.IBMVPCClient.GetVPCSubnetByName(subnetName) if err != nil { @@ -1279,7 +1281,7 @@ func (s *PowerVSClusterScope) ReconcileVPCSecurityGroups() error { } if sg != nil { s.V(3).Info("VPC security group already exists", "name", *sg.Name) - s.SetVPCSecurityGroup(*sg.Name, infrav1beta2.VPCSecurityGroupStatus{ + s.SetVPCSecurityGroupStatus(*sg.Name, infrav1beta2.VPCSecurityGroupStatus{ ID: sg.ID, RuleIDs: ruleIDs, ControllerCreated: ptr.To(false), @@ -1292,7 +1294,7 @@ func (s *PowerVSClusterScope) ReconcileVPCSecurityGroups() error { return fmt.Errorf("failed to create VPC security group: %w", err) } s.Info("VPC security group created", "name", *securityGroup.Name) - s.SetVPCSecurityGroup(*securityGroup.Name, infrav1beta2.VPCSecurityGroupStatus{ + s.SetVPCSecurityGroupStatus(*securityGroup.Name, infrav1beta2.VPCSecurityGroupStatus{ ID: securityGroupID, ControllerCreated: ptr.To(true), }) @@ -1431,7 +1433,7 @@ func (s *PowerVSClusterScope) createVPCSecurityGroupRulesAndSetStatus(ogSecurity } s.Info("VPC security group rules created", "security group name", *securityGroupName) - s.SetVPCSecurityGroup(*securityGroupName, infrav1beta2.VPCSecurityGroupStatus{ + s.SetVPCSecurityGroupStatus(*securityGroupName, infrav1beta2.VPCSecurityGroupStatus{ ID: securityGroupID, RuleIDs: ruleIDs, ControllerCreated: ptr.To(true), @@ -1835,7 +1837,6 @@ func (s *PowerVSClusterScope) checkTransitGatewayConnectionStatus(con tgapiv1.Tr s.V(3).Info("Checking the status of transit gateway connection", "name", *con.Name) switch *con.Status { case string(infrav1beta2.TransitGatewayConnectionStateAttached): - s.V(3).Info("Transit gateway connection is in attached state") return false, nil case string(infrav1beta2.TransitGatewayConnectionStateFailed): return false, fmt.Errorf("failed to attach connection to transit gateway, current status: %s", *con.Status) @@ -1887,6 +1888,10 @@ func (s *PowerVSClusterScope) createTransitGateway() error { return fmt.Errorf("failed to fetch resource group ID for resource group %v, ID is empty", s.ResourceGroup()) } + if s.IBMPowerVSCluster.Status.ServiceInstance == nil || s.IBMPowerVSCluster.Status.VPC == nil { + return fmt.Errorf("failed to proeceed with transit gateway creation as either one of VPC or PowerVS service instance reconciliation is not successful") + } + location, globalRouting, err := genUtil.GetTransitGatewayLocationAndRouting(s.Zone(), s.VPC().Region) if err != nil { return fmt.Errorf("failed to get transit gateway location and routing: %w", err) @@ -1894,11 +1899,11 @@ func (s *PowerVSClusterScope) createTransitGateway() error { // throw error when user tries to use local routing where global routing is required. // TODO: Add a webhook validation for below condition. - if s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting != nil && !*s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting && *globalRouting { + if s.IBMPowerVSCluster.Spec.TransitGateway != nil && s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting != nil && !*s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting && *globalRouting { return fmt.Errorf("failed to use local routing for transit gateway since powervs and vpc are in different region and requires global routing") } // setting global routing to true when it is set by user. - if s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting != nil && *s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting { + if s.IBMPowerVSCluster.Spec.TransitGateway != nil && s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting != nil && *s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting { globalRouting = ptr.To(true) } @@ -1942,7 +1947,7 @@ func (s *PowerVSClusterScope) ReconcileLoadBalancers() (bool, error) { loadBalancers = append(loadBalancers, loadBalancer) } for index, loadBalancer := range s.IBMPowerVSCluster.Spec.LoadBalancers { - if loadBalancer.Name == "" { + if loadBalancer.ID == nil && loadBalancer.Name == "" { loadBalancer.Name = fmt.Sprintf("%s-%d", *s.GetServiceName(infrav1beta2.ResourceTypeLoadBalancer), index) } loadBalancers = append(loadBalancers, loadBalancer) @@ -1983,6 +1988,7 @@ func (s *PowerVSClusterScope) ReconcileLoadBalancers() (bool, error) { return false, err } if loadBalancerStatus != nil { + s.V(3).Info("Found VPC load balancer in IBM Cloud", "id", *loadBalancerStatus.ID) s.SetLoadBalancerStatus(loadBalancer.Name, *loadBalancerStatus) continue } @@ -2033,7 +2039,7 @@ func (s *PowerVSClusterScope) checkLoadBalancerPort(lb infrav1beta2.VPCLoadBalan return nil } -// checkLoadBalancer checks loadBalancer in cloud. +// checkLoadBalancer checks if VPC load balancer by the given name exists in cloud. func (s *PowerVSClusterScope) checkLoadBalancer(lb infrav1beta2.VPCLoadBalancerSpec) (*infrav1beta2.VPCLoadBalancerStatus, error) { loadBalancer, err := s.IBMVPCClient.GetLoadBalancerByName(lb.Name) if err != nil { @@ -2331,7 +2337,9 @@ func (s *PowerVSClusterScope) fetchResourceGroupID() (string, error) { func (s *PowerVSClusterScope) fetchVPCCRN() (*string, error) { vpcID := s.GetVPCID() if vpcID == nil { - return nil, fmt.Errorf("VPC ID is empty") + if s.IBMPowerVSCluster.Spec.VPC != nil && s.IBMPowerVSCluster.Spec.VPC.ID != nil { + vpcID = s.IBMPowerVSCluster.Spec.VPC.ID + } } vpcDetails, _, err := s.IBMVPCClient.GetVPC(&vpcv1.GetVPCOptions{ ID: vpcID, @@ -2345,6 +2353,13 @@ func (s *PowerVSClusterScope) fetchVPCCRN() (*string, error) { // fetchPowerVSServiceInstanceCRN returns Power VS service instance CRN. func (s *PowerVSClusterScope) fetchPowerVSServiceInstanceCRN() (*string, error) { serviceInstanceID := s.GetServiceInstanceID() + if serviceInstanceID == "" { + if s.IBMPowerVSCluster.Spec.ServiceInstanceID != "" { + serviceInstanceID = s.IBMPowerVSCluster.Spec.ServiceInstanceID + } else if s.IBMPowerVSCluster.Spec.ServiceInstance != nil && s.IBMPowerVSCluster.Spec.ServiceInstance.ID != nil { + serviceInstanceID = *s.IBMPowerVSCluster.Spec.ServiceInstance.ID + } + } pvsDetails, _, err := s.ResourceClient.GetResourceInstance(&resourcecontrollerv2.GetResourceInstanceOptions{ ID: &serviceInstanceID, }) diff --git a/controllers/ibmpowervscluster_controller.go b/controllers/ibmpowervscluster_controller.go index a86b44d07..e8d82ce81 100644 --- a/controllers/ibmpowervscluster_controller.go +++ b/controllers/ibmpowervscluster_controller.go @@ -331,7 +331,11 @@ func (r *IBMPowerVSClusterReconciler) reconcile(clusterScope *scope.PowerVSClust } // update cluster object with loadbalancer host - loadBalancer := clusterScope.PublicLoadBalancer() + loadBalancer, err := clusterScope.PublicLoadBalancer() + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to fetch public loadbalancer: %w", err) + } + if loadBalancer == nil { return reconcile.Result{}, fmt.Errorf("failed to fetch public loadbalancer") }