From 26c09be0d47148a6d8e6a6f6308d1d7cf7350ab3 Mon Sep 17 00:00:00 2001 From: Daniel Lipovetsky Date: Wed, 3 Jul 2024 11:08:11 -0700 Subject: [PATCH] feat: Define ServiceLoadBalancer Configuration API (#778) **What problem does this PR solve?**: This adds an optional configuration for the ServiceLoadBalancer Addon, consisting of one or more IPv4 address ranges, e.g., ```yaml apiVersion: cluster.x-k8s.io/v1beta1 kind: Cluster metadata: name: spec: topology: variables: - name: clusterConfig value: addons: serviceLoadBalancer: provider: MetalLB configuration: addressRanges: - start: 10.100.1.1 end: 10.100.1.20 - start: 10.100.1.51 end: 10.100.1.70 ``` (This is a copy of https://github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pull/763. I had to close that after https://github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pull/755 added required checks that can't be run from PRs from public forks. ) **Which issue(s) this PR fixes**: Fixes # **How Has This Been Tested?**: **Special notes for your reviewer**: --- api/v1alpha1/addon_types.go | 21 ++++++++++ .../caren.nutanix.com_awsclusterconfigs.yaml | 25 +++++++++++ ...aren.nutanix.com_dockerclusterconfigs.yaml | 25 +++++++++++ ...ren.nutanix.com_nutanixclusterconfigs.yaml | 25 +++++++++++ api/v1alpha1/zz_generated.deepcopy.go | 42 ++++++++++++++++++- docs/content/addons/serviceloadbalancer.md | 31 +++++++++++++- 6 files changed, 166 insertions(+), 3 deletions(-) diff --git a/api/v1alpha1/addon_types.go b/api/v1alpha1/addon_types.go index c116c0992..9c3f70a81 100644 --- a/api/v1alpha1/addon_types.go +++ b/api/v1alpha1/addon_types.go @@ -257,4 +257,25 @@ type ServiceLoadBalancer struct { // +kubebuilder:validation:Enum=MetalLB // +kubebuilder:validation:Required Provider string `json:"provider"` + + // Configuration for the chosen ServiceLoadBalancer provider. + // +kubebuilder:validation:Optional + Configuration *ServiceLoadBalancerConfiguration `json:"configuration,omitempty"` +} + +type ServiceLoadBalancerConfiguration struct { + // AddressRanges is a list of IPv4 address ranges the + // provider uses to choose an address for a load balancer. + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + AddressRanges []AddressRange `json:"addressRanges"` +} + +// AddressRange defines an IPv4 range. +type AddressRange struct { + // +kubebuilder:validation:Format=ipv4 + Start string `json:"start"` + + // +kubebuilder:validation:Format=ipv4 + End string `json:"end"` } diff --git a/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml index c1a6926ec..922ab602e 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml @@ -218,6 +218,31 @@ spec: type: object serviceLoadBalancer: properties: + configuration: + description: Configuration for the chosen ServiceLoadBalancer provider. + properties: + addressRanges: + description: |- + AddressRanges is a list of IPv4 address ranges the + provider uses to choose an address for a load balancer. + items: + description: AddressRange defines an IPv4 range. + properties: + end: + format: ipv4 + type: string + start: + format: ipv4 + type: string + required: + - end + - start + type: object + minItems: 1 + type: array + required: + - addressRanges + type: object provider: description: |- The LoadBalancer-type Service provider to deploy. Not required in infrastructures where diff --git a/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml index c86fbd451..e3d2180dc 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml @@ -218,6 +218,31 @@ spec: type: object serviceLoadBalancer: properties: + configuration: + description: Configuration for the chosen ServiceLoadBalancer provider. + properties: + addressRanges: + description: |- + AddressRanges is a list of IPv4 address ranges the + provider uses to choose an address for a load balancer. + items: + description: AddressRange defines an IPv4 range. + properties: + end: + format: ipv4 + type: string + start: + format: ipv4 + type: string + required: + - end + - start + type: object + minItems: 1 + type: array + required: + - addressRanges + type: object provider: description: |- The LoadBalancer-type Service provider to deploy. Not required in infrastructures where diff --git a/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml index f780c5d0e..c408d8d4c 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml @@ -218,6 +218,31 @@ spec: type: object serviceLoadBalancer: properties: + configuration: + description: Configuration for the chosen ServiceLoadBalancer provider. + properties: + addressRanges: + description: |- + AddressRanges is a list of IPv4 address ranges the + provider uses to choose an address for a load balancer. + items: + description: AddressRange defines an IPv4 range. + properties: + end: + format: ipv4 + type: string + start: + format: ipv4 + type: string + required: + - end + - start + type: object + minItems: 1 + type: array + required: + - addressRanges + type: object provider: description: |- The LoadBalancer-type Service provider to deploy. Not required in infrastructures where diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index c546643ad..1a27f596a 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -398,6 +398,21 @@ func (in AdditionalSecurityGroup) DeepCopy() AdditionalSecurityGroup { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddressRange) DeepCopyInto(out *AddressRange) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressRange. +func (in *AddressRange) DeepCopy() *AddressRange { + if in == nil { + return nil + } + out := new(AddressRange) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CCM) DeepCopyInto(out *CCM) { *out = *in @@ -847,7 +862,7 @@ func (in *GenericAddons) DeepCopyInto(out *GenericAddons) { if in.ServiceLoadBalancer != nil { in, out := &in.ServiceLoadBalancer, &out.ServiceLoadBalancer *out = new(ServiceLoadBalancer) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -1424,6 +1439,11 @@ func (in *SecurityGroup) DeepCopy() *SecurityGroup { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceLoadBalancer) DeepCopyInto(out *ServiceLoadBalancer) { *out = *in + if in.Configuration != nil { + in, out := &in.Configuration, &out.Configuration + *out = new(ServiceLoadBalancerConfiguration) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceLoadBalancer. @@ -1436,6 +1456,26 @@ func (in *ServiceLoadBalancer) DeepCopy() *ServiceLoadBalancer { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceLoadBalancerConfiguration) DeepCopyInto(out *ServiceLoadBalancerConfiguration) { + *out = *in + if in.AddressRanges != nil { + in, out := &in.AddressRanges, &out.AddressRanges + *out = make([]AddressRange, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceLoadBalancerConfiguration. +func (in *ServiceLoadBalancerConfiguration) DeepCopy() *ServiceLoadBalancerConfiguration { + if in == nil { + return nil + } + out := new(ServiceLoadBalancerConfiguration) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SnapshotController) DeepCopyInto(out *SnapshotController) { *out = *in diff --git a/docs/content/addons/serviceloadbalancer.md b/docs/content/addons/serviceloadbalancer.md index cc767c146..5044ddb13 100644 --- a/docs/content/addons/serviceloadbalancer.md +++ b/docs/content/addons/serviceloadbalancer.md @@ -10,11 +10,15 @@ The Service Load Balancer is the component that backs this Kubernetes Service, e a Virtual IP, creating a machine that runs load balancer software, by delegating to APIs, such as the underlying infrastructure, or a hardware load balancer. +The Service Load Balancer can choose the Virtual IP from a pre-defined address range. You can use +CAREN to configure one or more IPv4 ranges. For additional options, configure the Service Load +Balancer yourself after it is deployed. + CAREN currently supports the following Service Load Balancers: - [MetalLB] -## Example +## Examples To enable deployment of MetalLB on a cluster, specify the following values: @@ -33,7 +37,30 @@ spec: provider: MetalLB ``` -See [MetalLB documentation] for details on configuration. +To enable MetalLB, and configure two address IPv4 ranges, specify the following values: + +```yaml +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Cluster +metadata: + name: +spec: + topology: + variables: + - name: clusterConfig + value: + addons: + serviceLoadBalancer: + provider: MetalLB + configuration: + addressRanges: + - start: 10.100.1.1 + end: 10.100.1.20 + - start: 10.100.1.51 + end: 10.100.1.70 +``` + +See [MetalLB documentation] for more configuration details. [external load balancer]: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ [MetalLB]: https://metallb.org