Skip to content

Commit 31d5a80

Browse files
authored
Add external cloud provider support for VPC (#1015)
1 parent c4b61c2 commit 31d5a80

File tree

14 files changed

+418
-66
lines changed

14 files changed

+418
-66
lines changed

cloud/scope/machine.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,18 @@ import (
2929
corev1 "k8s.io/api/core/v1"
3030
"k8s.io/apimachinery/pkg/types"
3131
"k8s.io/klog/v2/klogr"
32+
"k8s.io/utils/pointer"
3233

3334
"sigs.k8s.io/controller-runtime/pkg/client"
3435

3536
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
3637
"sigs.k8s.io/cluster-api/util/patch"
3738

3839
infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
40+
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/utils"
3941
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/vpc"
4042
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/endpoints"
43+
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/options"
4144
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/record"
4245
)
4346

@@ -426,3 +429,19 @@ func fetchImageID(image *infrav1beta2.IBMVPCResourceReference, m *MachineScope)
426429

427430
return nil, fmt.Errorf("image does not exist - failed to find an image ID")
428431
}
432+
433+
// SetProviderID will set the provider id for the machine.
434+
func (m *MachineScope) SetProviderID(id *string) error {
435+
// Based on the ProviderIDFormat version the providerID format will be decided.
436+
if options.ProviderIDFormatType(options.ProviderIDFormat) == options.ProviderIDFormatV2 {
437+
accountID, err := utils.GetAccountID()
438+
if err != nil {
439+
m.Logger.Error(err, "failed to get cloud account id", err.Error())
440+
return err
441+
}
442+
m.IBMVPCMachine.Spec.ProviderID = pointer.String(fmt.Sprintf("ibm://%s///%s/%s", accountID, m.Machine.Spec.ClusterName, *id))
443+
} else {
444+
m.IBMVPCMachine.Spec.ProviderID = pointer.String(fmt.Sprintf("ibmvpc://%s/%s", m.Machine.Spec.ClusterName, m.IBMVPCMachine.Name))
445+
}
446+
return nil
447+
}

cloud/scope/powervs_machine.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,11 @@ func (m *PowerVSMachineScope) GetZone() string {
573573
// SetProviderID will set the provider id for the machine.
574574
func (m *PowerVSMachineScope) SetProviderID(id *string) {
575575
// Based on the ProviderIDFormat version the providerID format will be decided.
576-
if options.PowerVSProviderIDFormatType(options.PowerVSProviderIDFormat) == options.PowerVSProviderIDFormatV2 {
576+
if options.ProviderIDFormatType(options.PowerVSProviderIDFormat) == options.PowerVSProviderIDFormatV2 {
577577
if id != nil {
578-
m.IBMPowerVSMachine.Spec.ProviderID = pointer.StringPtr(fmt.Sprintf("ibmpowervs://%s/%s/%s/%s", m.GetRegion(), m.GetZone(), m.IBMPowerVSMachine.Spec.ServiceInstanceID, *id))
578+
m.IBMPowerVSMachine.Spec.ProviderID = pointer.String(fmt.Sprintf("ibmpowervs://%s/%s/%s/%s", m.GetRegion(), m.GetZone(), m.IBMPowerVSMachine.Spec.ServiceInstanceID, *id))
579579
}
580580
} else {
581-
m.IBMPowerVSMachine.Spec.ProviderID = pointer.StringPtr(fmt.Sprintf("ibmpowervs://%s/%s", m.Machine.Spec.ClusterName, m.IBMPowerVSMachine.Name))
581+
m.IBMPowerVSMachine.Spec.ProviderID = pointer.String(fmt.Sprintf("ibmpowervs://%s/%s", m.Machine.Spec.ClusterName, m.IBMPowerVSMachine.Name))
582582
}
583583
}

config/manager/manager.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ spec:
2929
- "--leader-elect"
3030
- "--metrics-bind-addr=127.0.0.1:8080"
3131
- "--powervs-provider-id-fmt=${POWERVS_PROVIDER_ID_FORMAT:=v1}"
32+
- "--provider-id-fmt=${PROVIDER_ID_FORMAT:=v1}"
3233
- "--service-endpoint=${SERVICE_ENDPOINT:=none}"
3334
- "--v=${LOGLEVEL:=0}"
3435
image: controller:latest

controllers/ibmvpcmachine_controller.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
apierrors "k8s.io/apimachinery/pkg/api/errors"
3131
"k8s.io/apimachinery/pkg/runtime"
3232
"k8s.io/client-go/tools/record"
33-
"k8s.io/utils/pointer"
3433

3534
ctrl "sigs.k8s.io/controller-runtime"
3635
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -168,7 +167,9 @@ func (r *IBMVPCMachineReconciler) reconcileNormal(machineScope *scope.MachineSco
168167
},
169168
}
170169
_, ok := machineScope.IBMVPCMachine.Labels[capiv1beta1.MachineControlPlaneLabelName]
171-
machineScope.IBMVPCMachine.Spec.ProviderID = pointer.StringPtr(fmt.Sprintf("ibmvpc://%s/%s", machineScope.Machine.Spec.ClusterName, machineScope.IBMVPCMachine.Name))
170+
if err = machineScope.SetProviderID(instance.ID); err != nil {
171+
return ctrl.Result{}, errors.Wrapf(err, "failed to set provider id IBMVPCMachine %s/%s", machineScope.IBMVPCMachine.Namespace, machineScope.IBMVPCMachine.Name)
172+
}
172173
if ok {
173174
if machineScope.IBMVPCCluster.Spec.ControlPlaneLoadBalancer == nil {
174175
options := &vpcv1.AddInstanceNetworkInterfaceFloatingIPOptions{}

docs/book/src/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- [Prerequisites](./topics/vpc/prerequisites.md)
1111
- [Uploading an image](topics/vpc/uploading-an-image.md)
1212
- [Creating a cluster](./topics/vpc/creating-a-cluster.md)
13-
- [Creating a cluster with Load Balancer](./topics/vpc/load-balancer.md)
13+
- [Creating a cluster with Load Balancer and External Cloud Provider](./topics/vpc/load-balancer.md)
1414
- [Power VS Cluster](./topics/powervs/index.md)
1515
- [Prerequisites](./topics/powervs/prerequisites.md)
1616
- [Creating a cluster](./topics/powervs/creating-a-cluster.md)

docs/book/src/developer/tilt.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This document describes how to use [kind](https://kind.sigs.k8s.io) and [Tilt](h
1010
2. [kind](https://kind.sigs.k8s.io) v0.9 or newer (other clusters can be
1111
used if `preload_images_for_kind` is set to false)
1212
3. [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/)
13-
4. [Tilt](https://docs.tilt.dev/install.html) v0.22.2 or newer
13+
4. [Tilt](https://docs.tilt.dev/install.html) v0.30.8 or newer
1414
5. [envsubst](https://github.com/drone/envsubst) or similar to handle
1515
clusterctl var replacement
1616
6. Clone the [Cluster API](https://github.com/kubernetes-sigs/cluster-api) repository
@@ -55,9 +55,9 @@ extra_args:
5555
- '-v=5'
5656
```
5757
58-
### 1. Configuration to deploy workload cluster with external cloud controller manager
58+
### 1. Configuration to deploy Power VS workload cluster with external cloud controller manager
5959
60-
To deploy workload cluster with [Power VS cloud controller manager](/topics/powervs/external-cloud-provider.html) which is currently in experimental stage, Set `POWERVS_PROVIDER_ID_FORMAT` to `v2` and enable cluster resourceset feature gateunder kustomize_substitutions.
60+
To deploy workload cluster with [Power VS cloud controller manager](/topics/powervs/external-cloud-provider.html) which is currently in experimental stage, Set `POWERVS_PROVIDER_ID_FORMAT` to `v2` and enable cluster resourceset feature gate under kustomize_substitutions.
6161
Currently, [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) is experimental feature so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET` variable under kustomize_substitutions.
6262

6363
```yaml
@@ -74,7 +74,26 @@ kustomize_substitutions:
7474
EXP_CLUSTER_RESOURCE_SET: "true"
7575
```
7676

77-
### 2. Configuration to deploy workload cluster from ClusterClass template
77+
### 2. Configuration to deploy VPC workload cluster with external cloud controller manager
78+
79+
To deploy workload cluster with [cloud controller manager](/topics/vpc/load-balancer.html) which is currently in experimental stage, Set `PROVIDER_ID_FORMAT` to `v2` and enable cluster resourceset feature gate under kustomize_substitutions.
80+
Currently, [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) is experimental feature so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET` variable under kustomize_substitutions.
81+
82+
```yaml
83+
default_registry: "gcr.io/you-project-name-here"
84+
provider_repos:
85+
- ../cluster-api-provider-ibmcloud
86+
enable_providers:
87+
- ibmcloud
88+
- kubeadm-bootstrap
89+
- kubeadm-control-plane
90+
kustomize_substitutions:
91+
IBMCLOUD_API_KEY: "XXXXXXXXXXXXXXXXXX"
92+
PROVIDER_ID_FORMAT: "v2"
93+
EXP_CLUSTER_RESOURCE_SET: "true"
94+
```
95+
96+
### 3. Configuration to deploy workload cluster from ClusterClass template
7897

7998
To deploy workload cluster with [clusterclass-template](/topics/powervs/clusterclass-cluster.html) under kustomize_substitutions set `POWERVS_PROVIDER_ID_FORMAT` to `v2`.
8099
Currently, both [ClusterClass](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/index.html) and [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) are experimental feature so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET`, `CLUSTER_TOPOLOGY` variable under kustomize_substitutions.
@@ -94,7 +113,7 @@ kustomize_substitutions:
94113
CLUSTER_TOPOLOGY: "true"
95114
```
96115

97-
### 3. Configuration to deploy workload cluster with Custom Service Endpoint
116+
### 4. Configuration to deploy workload cluster with Custom Service Endpoint
98117

99118
To deploy workload cluster with Custom Service Endpoint, Set `SERVICE_ENDPOINT` environmental variable in semi-colon separated format: `${ServiceRegion}:${ServiceID1}=${URL1},${ServiceID2}=${URL2...}`
100119
```yaml

docs/book/src/getting-started.md

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,35 @@ it into a management cluster using `clusterctl`.
4848

4949
> Note: Refer [Regions-Zones Mapping](/reference/regions-zones-mapping.html) for more information.
5050

51-
> Note: To deploy workload cluster with [Power VS cloud controller manager](/topics/powervs/external-cloud-provider.html) which is currently in experimental stage. Set the `POWERVS_PROVIDER_ID_FORMAT` environmental variable.
52-
Currently, [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) is experimental feature so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET` environmental variables.
53-
```console
54-
export POWERVS_PROVIDER_ID_FORMAT=v2
55-
export EXP_CLUSTER_RESOURCE_SET=true
56-
```
57-
> Note: To deploy workload cluster with [Power VS clusterclass-template](/topics/powervs/clusterclass-cluster.html). Set the `POWERVS_PROVIDER_ID_FORMAT` environmental variable.
58-
Currently, both [ClusterClass](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/index.html) and [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) are experimental feature so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET`, `CLUSTER_TOPOLOGY` environmental variables.
51+
> Note: To deploy VPC workload cluster with [IBM cloud controller manager](/topics/vpc/load-balancer.html) which is currently in experimental stage. Set the `PROVIDER_ID_FORMAT` environmental variable.
52+
Currently, [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) is experimental feature, so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET` environmental variables.
5953
```console
60-
export POWERVS_PROVIDER_ID_FORMAT=v2
61-
export EXP_CLUSTER_RESOURCE_SET=true
62-
export CLUSTER_TOPOLOGY=true
63-
```
54+
export PROVIDER_ID_FORMAT=v2
55+
export EXP_CLUSTER_RESOURCE_SET=true
56+
```
6457

65-
> Note: To deploy workload cluster with Custom Service Endpoint, Set `SERVICE_ENDPOINT` environmental variable in semi-colon separated format:
58+
> Note: To deploy workload cluster with [Power VS cloud controller manager](/topics/powervs/external-cloud-provider.html) which is currently in experimental stage. Set the `POWERVS_PROVIDER_ID_FORMAT` environmental variable.
59+
Currently, [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) is experimental feature so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET` environmental variables.
6660
```console
67-
`${ServiceRegion1}:${ServiceID1}=${URL1},${ServiceID2}=${URL2};${ServiceRegion2}:${ServiceID1}=${URL1...}`.
68-
```
69-
Supported ServiceIDs include - `vpc, powervs, rc`
70-
```console
71-
export SERVICE_ENDPOINT=us-south:vpc=https://us-south-stage01.iaasdev.cloud.ibm.com,powervs=https://dal.power-iaas.test.cloud.ibm.com,rc=https://resource-controller.test.cloud.ibm.com
72-
```
61+
export POWERVS_PROVIDER_ID_FORMAT=v2
62+
export EXP_CLUSTER_RESOURCE_SET=true
63+
```
64+
> Note: To deploy workload cluster with [Power VS clusterclass-template](/topics/powervs/clusterclass-cluster.html). Set the `POWERVS_PROVIDER_ID_FORMAT` environmental variable.
65+
Currently, both [ClusterClass](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/index.html) and [ClusterResourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) are experimental feature so we need to enable the feature gate by setting `EXP_CLUSTER_RESOURCE_SET`, `CLUSTER_TOPOLOGY` environmental variables.
66+
```console
67+
export POWERVS_PROVIDER_ID_FORMAT=v2
68+
export EXP_CLUSTER_RESOURCE_SET=true
69+
export CLUSTER_TOPOLOGY=true
70+
```
71+
72+
> Note: To deploy workload cluster with Custom Service Endpoint, Set `SERVICE_ENDPOINT` environmental variable in semi-colon separated format:
73+
```console
74+
`${ServiceRegion1}:${ServiceID1}=${URL1},${ServiceID2}=${URL2};${ServiceRegion2}:${ServiceID1}=${URL1...}`.
75+
```
76+
Supported ServiceIDs include - `vpc, powervs, rc`
77+
```console
78+
export SERVICE_ENDPOINT=us-south:vpc=https://us-south-stage01.iaasdev.cloud.ibm.com,powervs=https://dal.power-iaas.test.cloud.ibm.com,rc=https://resource-controller.test.cloud.ibm.com
79+
```
7380

7481
2. Initialize local bootstrap cluster as a management cluster
7582

docs/book/src/topics/powervs/external-cloud-provider.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# IBM Power VS External Cloud Provider
2-
## This feature currently in experimental stage
2+
> ⚠️ **WARNING**: This feature is currently in experimental stage
33
44
## Steps
55

docs/book/src/topics/vpc/load-balancer.md

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
1-
## Provision workload Cluster with Load Balancer in IBM Cloud VPC
1+
## Provision workload Cluster with Load Balancer and external cloud provider in IBM Cloud VPC
22

33
> ⚠️ **WARNING**: This feature is currently in experimental stage
44
5-
Using clusterctl, render the yaml through templates and deploy the cluster
5+
## Steps
6+
7+
- To deploy a VPC workload cluster with Load Balancer IBM external [cloud provider](https://kubernetes.io/docs/concepts/architecture/cloud-controller/), create a cluster configuration with the [external cloud provider template](https://github.com/kubernetes-sigs/cluster-api-provider-ibmcloud/blob/main/templates/cluster-template-load-balancer.yaml)
8+
- The [external cloud provider template](https://github.com/kubernetes-sigs/cluster-api-provider-ibmcloud/blob/main/templates/cluster-template-load-balancer.yaml) will use [clusterresourceset](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-resource-set.html) and will create the necessary config map, secret and roles to run the cloud controller manager
9+
- As a prerequisite set the `provider-id-fmt` [flag](https://github.com/kubernetes-sigs/cluster-api-provider-ibmcloud/blob/ee70591709ac5ddaeed23222ccbfa78335d984a1/main.go#L183) with value v2
10+
11+
### Deploy VPC cluster with Load Balancer and IBM cloud provider
612

713
```console
8-
IBMVPC_REGION=us-south \
9-
IBMVPC_ZONE=us-south-1 \
10-
IBMVPC_RESOURCEGROUP=4f15679623607b855b1a27a67f20e1c7 \
11-
IBMVPC_NAME=ibm-vpc-0 \
12-
IBMVPC_IMAGE_NAME=capibm-vpc-ubuntu-2004-kube-v1-25-2 \
13-
IBMVPC_PROFILE=bx2-4x16 \
14-
IBMVPC_SSHKEY_NAME=capi-vpc-key \
15-
clusterctl generate cluster ibm-vpc-0 --kubernetes-version v1.22.0 \
16-
--target-namespace default \
17-
--control-plane-machine-count=3 \
18-
--worker-machine-count=1 \
19-
--flavor=load-balancer | kubectl apply -f -
14+
IBMCLOUD_API_KEY: "XXXXXXXXXXXXXXXXXX" \
15+
IBMVPC_REGION=us-south \
16+
IBMVPC_ZONE=us-south-1 \
17+
IBMVPC_RESOURCEGROUP_NAME="ibm-hypershift-dev" \
18+
IBMVPC_RESOURCEGROUP=4f15679623607b855b1a27a67f20e1c7 \
19+
IBMVPC_NAME=ibm-vpc-0 \
20+
IBMVPC_IMAGE_ID=r134-ea84bbec-7986-4ff5-8489-d9ec34611dd4 \
21+
IBMVPC_PROFILE=bx2-4x16 \
22+
IBMVPC_SSHKEY_ID=r134-2a82b725-e570-43d3-8b23-9539e8641944 \
23+
IBMACCOUNT_ID="ibm-accountid" \
24+
BASE64_API_KEY=$(echo -n $IBMCLOUD_API_KEY | base64) \
25+
clusterctl generate cluster ibm-vpc-0 --kubernetes-version v1.25.2 \
26+
--target-namespace default \
27+
--control-plane-machine-count=1 \
28+
--worker-machine-count=2 \
29+
--flavor=load-balancer | kubectl apply -f -
2030
```
2131

2232
**Change disk size for the boot volume**

main.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,21 @@ func initFlags(fs *pflag.FlagSet) {
165165
"The minimum interval at which watched resources are reconciled.",
166166
)
167167

168+
// TODO: Deprecate it to use provider-id-fmt for both vpc and power vs
168169
fs.StringVar(
169170
&options.PowerVSProviderIDFormat,
170171
"powervs-provider-id-fmt",
171172
string(options.PowerVSProviderIDFormatV1),
172173
"ProviderID format is used set the Provider ID format for Machine",
173174
)
174175

176+
fs.StringVar(
177+
&options.ProviderIDFormat,
178+
"provider-id-fmt",
179+
string(options.ProviderIDFormatV1),
180+
"ProviderID format is used set the Provider ID format for Machine (Currently for VPC machines only)",
181+
)
182+
175183
fs.StringVar(
176184
&endpoints.ServiceEndpointFormat,
177185
"service-endpoint",
@@ -181,14 +189,21 @@ func initFlags(fs *pflag.FlagSet) {
181189
}
182190

183191
func validateFlags() error {
184-
switch options.PowerVSProviderIDFormatType(options.PowerVSProviderIDFormat) {
192+
switch options.ProviderIDFormatType(options.PowerVSProviderIDFormat) {
185193
case options.PowerVSProviderIDFormatV1:
186-
setupLog.Info("Using v1 version of ProviderID format")
194+
setupLog.Info("Using v1 version of Power VS ProviderID format")
187195
case options.PowerVSProviderIDFormatV2:
188-
setupLog.Info("Using v2 version of ProviderID format")
196+
setupLog.Info("Using v2 version of Power VS ProviderID format")
197+
default:
198+
return fmt.Errorf("invalid value for flag powervs-provider-id-fmt: %s, Supported values: v1, v2 ", options.PowerVSProviderIDFormat)
199+
}
200+
switch options.ProviderIDFormatType(options.ProviderIDFormat) {
201+
case options.ProviderIDFormatV1:
202+
setupLog.Info("Using v1 version of VPC ProviderID format")
203+
case options.ProviderIDFormatV2:
204+
setupLog.Info("Using v2 version of VPC ProviderID format")
189205
default:
190-
errStr := fmt.Errorf("invalid value for flag powervs-provider-id-fmt: %s, Supported values: v1, v2 ", options.PowerVSProviderIDFormat)
191-
return errStr
206+
return fmt.Errorf("invalid value for flag provider-id-fmt: %s, Supported values: %s, %s ", options.ProviderIDFormat, options.ProviderIDFormatV1, options.ProviderIDFormatV2)
192207
}
193208
return nil
194209
}

0 commit comments

Comments
 (0)