From 233a44458a886c24cbcba29d91521fdf59e3f618 Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Mon, 16 Sep 2024 12:01:44 -0400 Subject: [PATCH] openstack: support setting LB IP Add support for setting the (deprecated) Service field: `loadBalancerIP` on platform OpenStack when the LB is not internal. --- manifests/00-custom-resource-definition.yaml | 44 +++++++++++++++++++ pkg/operator/controller/ingress/controller.go | 29 ++++++++++++ .../ingress/load_balancer_service.go | 9 ++++ 3 files changed, 82 insertions(+) diff --git a/manifests/00-custom-resource-definition.yaml b/manifests/00-custom-resource-definition.yaml index 6adf7cd357..65cfdc9d24 100644 --- a/manifests/00-custom-resource-definition.yaml +++ b/manifests/00-custom-resource-definition.yaml @@ -574,6 +574,24 @@ spec: - PROXY type: string type: object + openstack: + description: "openstack provides configuration settings + that are specific to OpenStack load balancers. \n If + empty, defaults will be applied. See specific openstack + fields for details about their defaults." + properties: + loadBalancerIP: + description: loadBalancerIP specifies the floating + IP address that the load balancer will use. When + not specified, an IP address will be assigned randomly + by the OpenStack cloud provider. This value must + be a valid IPv4 or IPv6 address. + type: string + x-kubernetes-validations: + - message: loadBalancerIP must be a valid IPv4 or + IPv6 address + rule: isIP(self) + type: object type: description: type is the underlying infrastructure provider for the load balancer. Allowed values are "AWS", "Azure", @@ -592,6 +610,10 @@ spec: required: - type type: object + x-kubernetes-validations: + - message: openstack is not permitted when type is not OpenStack + rule: 'has(self.type) && self.type == ''OpenStack'' ? true + : !has(self.openstack)' scope: description: scope indicates the scope at which the load balancer is exposed. Possible values are "External" and "Internal". @@ -2440,6 +2462,24 @@ spec: - PROXY type: string type: object + openstack: + description: "openstack provides configuration settings + that are specific to OpenStack load balancers. \n If + empty, defaults will be applied. See specific openstack + fields for details about their defaults." + properties: + loadBalancerIP: + description: loadBalancerIP specifies the floating + IP address that the load balancer will use. When + not specified, an IP address will be assigned randomly + by the OpenStack cloud provider. This value must + be a valid IPv4 or IPv6 address. + type: string + x-kubernetes-validations: + - message: loadBalancerIP must be a valid IPv4 or + IPv6 address + rule: isIP(self) + type: object type: description: type is the underlying infrastructure provider for the load balancer. Allowed values are "AWS", "Azure", @@ -2458,6 +2498,10 @@ spec: required: - type type: object + x-kubernetes-validations: + - message: openstack is not permitted when type is not OpenStack + rule: 'has(self.type) && self.type == ''OpenStack'' ? true + : !has(self.openstack)' scope: description: scope indicates the scope at which the load balancer is exposed. Possible values are "External" and "Internal". diff --git a/pkg/operator/controller/ingress/controller.go b/pkg/operator/controller/ingress/controller.go index 43984ec1a4..38a9d22c24 100644 --- a/pkg/operator/controller/ingress/controller.go +++ b/pkg/operator/controller/ingress/controller.go @@ -617,6 +617,27 @@ func setDefaultPublishingStrategy(ic *operatorv1.IngressController, platformStat statusLB.ProviderParameters.IBM.Protocol = specProtocol changed = true } + case operatorv1.OpenStackLoadBalancerProvider: + // The only provider parameter that is supported + // for OpenStack is the LoadBalancerIP parameter. + var statusLoadBalancerIP string + specLoadBalancerIP := specLB.ProviderParameters.OpenStack.LoadBalancerIP + if statusLB.ProviderParameters != nil && statusLB.ProviderParameters.OpenStack != nil { + statusLoadBalancerIP = statusLB.ProviderParameters.OpenStack.LoadBalancerIP + } + if specLoadBalancerIP != statusLoadBalancerIP { + if statusLB.ProviderParameters == nil { + statusLB.ProviderParameters = &operatorv1.ProviderLoadBalancerParameters{} + } + if len(statusLB.ProviderParameters.Type) == 0 { + statusLB.ProviderParameters.Type = operatorv1.OpenStackLoadBalancerProvider + } + if statusLB.ProviderParameters.OpenStack == nil { + statusLB.ProviderParameters.OpenStack = &operatorv1.OpenStackLoadBalancerParameters{} + } + statusLB.ProviderParameters.OpenStack.LoadBalancerIP = specLoadBalancerIP + changed = true + } } return changed } @@ -739,6 +760,14 @@ func setDefaultProviderParameters(lbs *operatorv1.LoadBalancerStrategy, ingressC if lbs.ProviderParameters.IBM == nil { lbs.ProviderParameters.IBM = &operatorv1.IBMLoadBalancerParameters{} } + case operatorv1.OpenStackLoadBalancerProvider: + if lbs.ProviderParameters == nil { + lbs.ProviderParameters = &operatorv1.ProviderLoadBalancerParameters{} + } + lbs.ProviderParameters.Type = provider + if lbs.ProviderParameters.OpenStack == nil { + lbs.ProviderParameters.OpenStack = &operatorv1.OpenStackLoadBalancerParameters{} + } } } diff --git a/pkg/operator/controller/ingress/load_balancer_service.go b/pkg/operator/controller/ingress/load_balancer_service.go index 7cef35dda3..1ec9a55e77 100644 --- a/pkg/operator/controller/ingress/load_balancer_service.go +++ b/pkg/operator/controller/ingress/load_balancer_service.go @@ -475,6 +475,15 @@ func desiredLoadBalancerService(ci *operatorv1.IngressController, deploymentRef if !isInternal { service.Annotations[alibabaCloudLBAddressTypeAnnotation] = alibabaCloudLBAddressTypeInternet } + case configv1.OpenStackPlatformType: + // Set a floating IP only if the load balancer is external. + if !isInternal { + if lb != nil && lb.ProviderParameters != nil && + lb.ProviderParameters.Type == operatorv1.OpenStackLoadBalancerProvider && + lb.ProviderParameters.OpenStack != nil { + service.Spec.LoadBalancerIP = lb.ProviderParameters.OpenStack.LoadBalancerIP + } + } } // Azure load balancers are not customizable and are set to (2 fail @ 5s interval, 2 healthy) // GCP load balancers are not customizable and are set to (3 fail @ 8s interval, 1 healthy)