From 0e0f3e3f26bfe8bc3737999886c20e3afd1b3c9c Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Mon, 16 Sep 2024 12:01:44 -0400 Subject: [PATCH] WIP - 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..a2ebf364b4 100644 --- a/pkg/operator/controller/ingress/load_balancer_service.go +++ b/pkg/operator/controller/ingress/load_balancer_service.go @@ -398,6 +398,15 @@ func desiredLoadBalancerService(ci *operatorv1.IngressController, deploymentRef for name, value := range annotation { service.Annotations[name] = value } + + // Set the Load Balancer IP for external load balancers on OpenStack only + if platform.Type == configv1.OpenStackPlatformType { + if lb != nil && lb.ProviderParameters != nil && + lb.ProviderParameters.Type == operatorv1.OpenStackLoadBalancerProvider && + lb.ProviderParameters.OpenStack != nil { + service.Spec.LoadBalancerIP = lb.ProviderParameters.OpenStack.LoadBalancerIP + } + } } switch platform.Type { case configv1.AWSPlatformType: