Skip to content

Commit

Permalink
Support previous cluster creation workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Karthik-K-N committed Feb 9, 2024
1 parent 78987ec commit dea3da8
Show file tree
Hide file tree
Showing 16 changed files with 147 additions and 196 deletions.
2 changes: 1 addition & 1 deletion api/v1beta1/ibmpowervs_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func Convert_v1beta2_IBMPowerVSMachineSpec_To_v1beta1_IBMPowerVSMachineSpec(in *
}

func Convert_v1beta2_IBMPowerVSClusterSpec_To_v1beta1_IBMPowerVSClusterSpec(in *infrav1beta2.IBMPowerVSClusterSpec, out *IBMPowerVSClusterSpec, s apiconversion.Scope) error {
if in.ServiceInstance.ID != nil {
if in.ServiceInstance != nil && in.ServiceInstance.ID != nil {
out.ServiceInstanceID = *in.ServiceInstance.ID
}
return autoConvert_v1beta2_IBMPowerVSClusterSpec_To_v1beta1_IBMPowerVSClusterSpec(in, out, s)
Expand Down
2 changes: 0 additions & 2 deletions api/v1beta2/ibmpowervscluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ type IBMPowerVSClusterSpec struct {

// zone is the name of Power VS zone where the cluster will be created
// possible values can be found here https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-creating-power-virtual-server.
// when omitted syd04 will be set as default zone.
// +kubebuilder:default=dal10
// +optional
Zone *string `json:"zone,omitempty"`

Expand Down
88 changes: 71 additions & 17 deletions cloud/scope/powervs_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,45 @@ func NewPowerVSClusterScope(params PowerVSClusterScopeParams) (*PowerVSClusterSc
return nil, err
}

options := powervs.ServiceOptions{
IBMPIOptions: &ibmpisession.IBMPIOptions{
Debug: params.Logger.V(DEBUGLEVEL).Enabled(),
},
}

if params.IBMPowerVSCluster.Spec.ServiceInstanceID != "" {
rc, err := resourcecontroller.NewService(resourcecontroller.ServiceOptions{})
if err != nil {
return nil, err
}

// Fetch the resource controller endpoint.
if rcEndpoint := endpoints.FetchRCEndpoint(params.ServiceEndpoint); rcEndpoint != "" {
if err := rc.SetServiceURL(rcEndpoint); err != nil {
return nil, fmt.Errorf("failed to set resource controller endpoint: %w", err)
}
}

res, _, err := rc.GetResourceInstance(
&resourcecontrollerv2.GetResourceInstanceOptions{
ID: core.StringPtr(params.IBMPowerVSCluster.Spec.ServiceInstanceID),
})
if err != nil {
err = fmt.Errorf("failed to get resource instance: %w", err)
return nil, err
}
options.Zone = *res.RegionID
options.CloudInstanceID = params.IBMPowerVSCluster.Spec.ServiceInstanceID
} else {
options.Zone = *params.IBMPowerVSCluster.Spec.Zone
}

// TODO(karhtik-k-n): may be optimize NewService to use the session created here
powerVSClient, err := powervs.NewService(options)
if err != nil {
return nil, fmt.Errorf("error failed to create power vs client %w", err)
}

auth, err := authenticator.GetAuthenticator()
if err != nil {
return nil, fmt.Errorf("error failed to create authenticator %w", err)
Expand All @@ -177,23 +216,26 @@ func NewPowerVSClusterScope(params PowerVSClusterScopeParams) (*PowerVSClusterSc
sessionOptions := &ibmpisession.IBMPIOptions{
Authenticator: auth,
UserAccount: account,
Zone: *params.IBMPowerVSCluster.Spec.Zone,
Zone: options.Zone,
}
session, err := ibmpisession.NewIBMPISession(sessionOptions)
if err != nil {
return nil, fmt.Errorf("error failed to get power vs session %w", err)
}
options := powervs.ServiceOptions{
IBMPIOptions: &ibmpisession.IBMPIOptions{
Debug: params.Logger.V(DEBUGLEVEL).Enabled(),
Zone: *params.IBMPowerVSCluster.Spec.Zone,
},
}
// TODO(karhtik-k-n): may be optimize NewService to use the session created here
powerVSClient, err := powervs.NewService(options)
if err != nil {
return nil, fmt.Errorf("error failed to create power vs client %w", err)

if !genUtil.CreateInfra(*params.IBMPowerVSCluster) {
return &PowerVSClusterScope{
session: session,
Logger: params.Logger,
Client: params.Client,
patchHelper: helper,
Cluster: params.Cluster,
IBMPowerVSCluster: params.IBMPowerVSCluster,
ServiceEndpoint: params.ServiceEndpoint,
IBMPowerVSClient: powerVSClient,
}, nil
}

if params.IBMPowerVSCluster.Spec.VPC == nil || params.IBMPowerVSCluster.Spec.VPC.Region == nil {
return nil, fmt.Errorf("error failed to generate vpc client as VPC info is nil")
}
Expand Down Expand Up @@ -334,6 +376,12 @@ func (s *PowerVSClusterScope) SetStatus(resourceType ResourceType, resource infr
return
}
s.IBMPowerVSCluster.Status.DHCPServer.Set(resource)
case COSInstance:
if s.IBMPowerVSCluster.Status.COSInstance == nil {
s.IBMPowerVSCluster.Status.COSInstance = &resource
return
}
s.IBMPowerVSCluster.Status.COSInstance.Set(resource)
}
}

Expand Down Expand Up @@ -1246,15 +1294,15 @@ func (s *PowerVSClusterScope) ReconcileCOSInstance() error {
return err
}
if cosServiceInstanceStatus != nil {
s.SetStatus(TransitGateway, infrav1beta2.ResourceReference{ID: cosServiceInstanceStatus.GUID, ControllerCreated: pointer.Bool(false)})
s.SetStatus(COSInstance, infrav1beta2.ResourceReference{ID: cosServiceInstanceStatus.GUID, ControllerCreated: pointer.Bool(false)})
} else {
// create COS service instance
cosServiceInstanceStatus, err = s.createCOSServiceInstance()
if err != nil {
s.Error(err, "error creating cos service instance")
return err
}
s.SetStatus(TransitGateway, infrav1beta2.ResourceReference{ID: cosServiceInstanceStatus.GUID, ControllerCreated: pointer.Bool(true)})
s.SetStatus(COSInstance, infrav1beta2.ResourceReference{ID: cosServiceInstanceStatus.GUID, ControllerCreated: pointer.Bool(true)})
}

apiKey := os.Getenv("IBMCLOUD_API_KEY")
Expand All @@ -1271,7 +1319,9 @@ func (s *PowerVSClusterScope) ReconcileCOSInstance() error {
s.COSClient = cosClient

// check bucket exist in service instance
if exist, err := s.checkCOSBucket(); exist || err != nil {
if exist, err := s.checkCOSBucket(); exist {
return nil
} else if err != nil {
s.Error(err, "error checking cos bucket")
return err
}
Expand Down Expand Up @@ -1319,6 +1369,8 @@ func (s *PowerVSClusterScope) createCOSBucket() error {
// If bucket already exists, all good.
case s3.ErrCodeBucketAlreadyOwnedByYou:
return nil
case s3.ErrCodeBucketAlreadyExists:
return nil
default:
return fmt.Errorf("error creating COS bucket %w", err)
}
Expand Down Expand Up @@ -1353,12 +1405,10 @@ func (s *PowerVSClusterScope) createCOSServiceInstance() (*resourcecontrollerv2.
// return nil, fmt.Errorf("error retrieving id info for powervs service %w", err)
//}

//TODO(karthik-k-n): add funciton to fetch name
target := "Global"
serviceInstanceName := fmt.Sprintf("%s-%s", s.InfraCluster().GetName(), "cosInstance")
// create service instance
serviceInstance, _, err := s.ResourceClient.CreateResourceInstance(&resourcecontrollerv2.CreateResourceInstanceOptions{
Name: &serviceInstanceName,
Name: s.GetServiceName(COSInstance),
Target: &target,
ResourceGroup: &resourceGroupID,
ResourcePlanID: pointer.String(cosResourcePlanID),
Expand Down Expand Up @@ -1708,6 +1758,10 @@ func (s *PowerVSClusterScope) DeleteCosInstance() error {
return fmt.Errorf("error fetching COS instance: %w", err)
}

if cosInstance != nil && (*cosInstance.State == "pending_reclamation" || *cosInstance.State == string(infrav1beta2.ServiceInstanceStateRemoved)) {
return nil
}

_, err = s.ResourceClient.DeleteResourceInstance(&resourcecontrollerv2.DeleteResourceInstanceOptions{
ID: cosInstance.ID,
Recursive: pointer.Bool(true),
Expand Down
7 changes: 4 additions & 3 deletions cloud/scope/powervs_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,22 @@ import (
"context"
"errors"
"fmt"
"github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"

"github.com/go-logr/logr"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/resourcecontroller"

"github.com/IBM-Cloud/power-go-client/ibmpisession"
"github.com/IBM-Cloud/power-go-client/power/models"
"github.com/IBM/go-sdk-core/v5/core"
"k8s.io/klog/v2/klogr"
"github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"

"k8s.io/klog/v2/klogr"
"sigs.k8s.io/controller-runtime/pkg/client"

"sigs.k8s.io/cluster-api/util/patch"

infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/powervs"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/resourcecontroller"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/endpoints"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/record"
)
Expand Down
60 changes: 32 additions & 28 deletions cloud/scope/powervs_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"os"
"path"
"regexp"
"sigs.k8s.io/cluster-api/util"
"strconv"
"strings"

Expand All @@ -53,6 +52,7 @@ import (

capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
capierrors "sigs.k8s.io/cluster-api/errors"
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/patch"

infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
Expand All @@ -63,7 +63,7 @@ import (
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/endpoints"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/options"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/record"
putil "sigs.k8s.io/cluster-api-provider-ibmcloud/util"
genUtil "sigs.k8s.io/cluster-api-provider-ibmcloud/util"
)

// PowerVSMachineScopeParams defines the input parameters used to create a new PowerVSMachineScope.
Expand All @@ -82,9 +82,8 @@ type PowerVSMachineScopeParams struct {
// PowerVSMachineScope defines a scope defined around a Power VS Machine.
type PowerVSMachineScope struct {
logr.Logger
Client client.Client
patchHelper *patch.Helper
serviceInstanceID string
Client client.Client
patchHelper *patch.Helper

IBMPowerVSClient powervs.PowerVS
IBMVPCClient vpc.Vpc
Expand Down Expand Up @@ -153,36 +152,36 @@ func NewPowerVSMachineScope(params PowerVSMachineScopeParams) (scope *PowerVSMac
scope.Logger.V(3).Info("Overriding the default resource controller endpoint")
}

region := endpoints.ConstructRegionFromZone(*params.IBMPowerVSCluster.Spec.Zone)
scope.SetRegion(region)
scope.SetZone(*params.IBMPowerVSCluster.Spec.Zone)

var serviceInstanceID string
var serviceInstanceID, serviceInstanceName string
if params.IBMPowerVSMachine.Spec.ServiceInstanceID != "" {
serviceInstanceID = params.IBMPowerVSMachine.Spec.ServiceInstanceID
} else {
name := fmt.Sprintf("%s-%s", params.IBMPowerVSCluster.GetName(), "serviceInstance")
serviceInstanceName = fmt.Sprintf("%s-%s", params.IBMPowerVSCluster.GetName(), "serviceInstance")
if params.IBMPowerVSCluster.Spec.ServiceInstance != nil && params.IBMPowerVSCluster.Spec.ServiceInstance.Name != nil {
name = *params.IBMPowerVSCluster.Spec.ServiceInstance.Name
serviceInstanceName = *params.IBMPowerVSCluster.Spec.ServiceInstance.Name
}
serviceInstance, err := rc.GetServiceInstance("", name)
if err != nil {
params.Logger.Error(err, "error failed to get service instance id from name", "name", name)
return nil, err
}
if serviceInstance == nil {
return nil, fmt.Errorf("service instance %s is not yet created", name)
}
if *serviceInstance.State != "active" {
return nil, fmt.Errorf("service instance %s is not in active state", name)
}
serviceInstanceID = *serviceInstance.GUID
}
serviceInstance, err := rc.GetServiceInstance(serviceInstanceID, serviceInstanceName)
if err != nil {
params.Logger.Error(err, "error failed to get service instance details", "name", serviceInstanceName, "id", serviceInstanceID)
return nil, err
}
if serviceInstance == nil {
return nil, fmt.Errorf("service instance %s is not yet created", serviceInstanceName)
}
if *serviceInstance.State != "active" {
return nil, fmt.Errorf("service instance name: %s id: %s is not in active state", serviceInstanceName, serviceInstanceID)
}
serviceInstanceID = *serviceInstance.GUID

region := endpoints.ConstructRegionFromZone(*serviceInstance.RegionID)
scope.SetRegion(region)
scope.SetZone(*serviceInstance.RegionID)

serviceOptions := powervs.ServiceOptions{
IBMPIOptions: &ibmpisession.IBMPIOptions{
Debug: params.Logger.V(DEBUGLEVEL).Enabled(),
Zone: *params.IBMPowerVSCluster.Spec.Zone,
Zone: *serviceInstance.RegionID,
},
CloudInstanceID: serviceInstanceID,
}
Expand All @@ -200,9 +199,16 @@ func NewPowerVSMachineScope(params PowerVSMachineScopeParams) (scope *PowerVSMac
}
c.WithClients(serviceOptions)

scope.IBMPowerVSClient = c
scope.DHCPIPCacheStore = params.DHCPIPCacheStore

if !genUtil.CreateInfra(*params.IBMPowerVSCluster) {
return scope, nil
}

var vpcRegion string
if params.IBMPowerVSCluster.Spec.VPC == nil || params.IBMPowerVSCluster.Spec.VPC.Region == nil {
vpcRegion, err = putil.VPCRegionForPowerVSRegion(scope.GetRegion())
vpcRegion, err = genUtil.VPCRegionForPowerVSRegion(scope.GetRegion())
if err != nil {
return nil, fmt.Errorf("failed to create vpc client, error getting vpc region %v", err)
}
Expand All @@ -216,8 +222,6 @@ func NewPowerVSMachineScope(params PowerVSMachineScopeParams) (scope *PowerVSMac
}

scope.IBMVPCClient = vpcClient
scope.IBMPowerVSClient = c
scope.DHCPIPCacheStore = params.DHCPIPCacheStore
scope.ResourceClient = rc
return scope, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,8 @@ spec:
type: object
type: array
zone:
default: dal10
description: zone is the name of Power VS zone where the cluster will
be created possible values can be found here https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-creating-power-virtual-server.
when omitted syd04 will be set as default zone.
type: string
required:
- network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,8 @@ spec:
type: object
type: array
zone:
default: dal10
description: zone is the name of Power VS zone where the cluster
will be created possible values can be found here https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-creating-power-virtual-server.
when omitted syd04 will be set as default zone.
type: string
required:
- network
Expand Down
Loading

0 comments on commit dea3da8

Please sign in to comment.