From 83101276952f136f445f0829e2b21f8253bcec3c Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Mon, 14 Aug 2023 11:50:44 +0200 Subject: [PATCH] Create swiftproxy route and svc overrides Creates the route for the swift, also allows to customize the route via override. Generats the service override for the env with what is configured in the externalEndpoints, or specified in the service template override. Depends-On: https://github.com/openstack-k8s-operators/lib-common/pull/313 Depends-On: https://github.com/openstack-k8s-operators/keystone-operator/pull/289 Depends-On: https://github.com/openstack-k8s-operators/swift-operator/pull/43 Jira: OSP-26690 --- ....openstack.org_openstackcontrolplanes.yaml | 101 ++++++++++++++++++ apis/core/v1beta1/conditions.go | 3 + .../v1beta1/openstackcontrolplane_types.go | 5 + apis/core/v1beta1/zz_generated.deepcopy.go | 1 + ....openstack.org_openstackcontrolplanes.yaml | 101 ++++++++++++++++++ ...controlplane_galera_network_isolation.yaml | 12 +++ ...ne_galera_network_isolation_3replicas.yaml | 12 +++ ...enstackcontrolplane_network_isolation.yaml | 12 +++ pkg/openstack/swift.go | 55 ++++++++++ 9 files changed, 302 insertions(+) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index fbe93f3b4..ce65fe5e0 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -12722,6 +12722,107 @@ spec: enabled: default: true type: boolean + proxyOverride: + properties: + route: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + alternateBackends: + items: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + maxItems: 3 + type: array + host: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + path: + pattern: ^/ + type: string + port: + properties: + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - targetPort + type: object + subdomain: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + tls: + properties: + caCertificate: + type: string + certificate: + type: string + destinationCACertificate: + type: string + insecureEdgeTerminationPolicy: + type: string + key: + type: string + termination: + enum: + - edge + - reencrypt + - passthrough + type: string + required: + - termination + type: object + to: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + wildcardPolicy: + enum: + - None + - Subdomain + - "" + type: string + type: object + type: object + type: object template: properties: storageClass: diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 753da8170..826001c17 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -120,6 +120,9 @@ const ( // OpenStackControlPlaneSwiftReadyCondition Status=True condition which indicates if Swift is configured and operational OpenStackControlPlaneSwiftReadyCondition condition.Type = "OpenStackControlPlaneSwiftReady" + // OpenStackControlPlaneExposeSwiftReadyCondition Status=True condition which indicates if Swift is exposed via a route + OpenStackControlPlaneExposeSwiftReadyCondition condition.Type = "OpenStackControlPlaneExposeSwiftReady" + // OpenStackControlPlaneSwiftReadyInitMessage OpenStackControlPlaneSwiftReadyInitMessage = "OpenStackControlPlane Swift not started" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 355447c1d..fc65120a9 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -547,6 +547,11 @@ type SwiftSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating Swift Resources Template swiftv1.SwiftSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // ProxyOverride, provides the ability to override the generated manifest of several child resources. + ProxyOverride Override `json:"proxyOverride,omitempty"` } // OctaviaSection defines the desired state of the Octavia service diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 18c265a6b..8074d8740 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -631,6 +631,7 @@ func (in *RabbitmqTemplate) DeepCopy() *RabbitmqTemplate { func (in *SwiftSection) DeepCopyInto(out *SwiftSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.ProxyOverride.DeepCopyInto(&out.ProxyOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index fbe93f3b4..ce65fe5e0 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -12722,6 +12722,107 @@ spec: enabled: default: true type: boolean + proxyOverride: + properties: + route: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + alternateBackends: + items: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + maxItems: 3 + type: array + host: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + path: + pattern: ^/ + type: string + port: + properties: + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - targetPort + type: object + subdomain: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + tls: + properties: + caCertificate: + type: string + certificate: + type: string + destinationCACertificate: + type: string + insecureEdgeTerminationPolicy: + type: string + key: + type: string + termination: + enum: + - edge + - reencrypt + - passthrough + type: string + required: + - termination + type: object + to: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + wildcardPolicy: + enum: + - None + - Subdomain + - "" + type: string + type: object + type: object + type: object template: properties: storageClass: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 6e52d1b07..5b231b843 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -284,6 +284,8 @@ spec: serviceUser: ceilometer swift: enabled: true + proxyOverride: + route: {} template: swiftRing: ringReplicas: 1 @@ -291,6 +293,16 @@ spec: replicas: 1 swiftProxy: replicas: 1 + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer octavia: enabled: false template: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml index 769319d20..a27a51419 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -284,6 +284,8 @@ spec: serviceUser: ceilometer swift: enabled: true + proxyOverride: + route: {} template: swiftRing: ringReplicas: 1 @@ -291,6 +293,16 @@ spec: replicas: 1 swiftProxy: replicas: 1 + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer octavia: enabled: false template: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index c975bcb4a..f26b23651 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -272,6 +272,8 @@ spec: serviceUser: ceilometer swift: enabled: true + proxyOverride: + route: {} template: swiftRing: ringReplicas: 1 @@ -279,6 +281,16 @@ spec: replicas: 1 swiftProxy: replicas: 1 + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer octavia: enabled: false template: diff --git a/pkg/openstack/swift.go b/pkg/openstack/swift.go index ae40f9dc3..b47ee2a4f 100644 --- a/pkg/openstack/swift.go +++ b/pkg/openstack/swift.go @@ -4,14 +4,20 @@ import ( "context" "fmt" + "github.com/openstack-k8s-operators/lib-common/modules/common" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/reconcile" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" swiftv1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,12 +35,61 @@ func ReconcileSwift(ctx context.Context, instance *corev1beta1.OpenStackControlP return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneSwiftReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeSwiftReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Swift.Template.SwiftProxy.Override.Service == nil { + instance.Spec.Swift.Template.SwiftProxy.Override.Service = map[string]service.RoutedOverrideSpec{} + } + instance.Spec.Swift.Template.SwiftProxy.Override.Service[string(endpointType)] = + AddServiceComponentLabel( + ptr.To(instance.Spec.Swift.Template.SwiftProxy.Override.Service[string(endpointType)]), + swift.Name) + } + + // When component services got created check if there is the need to create a route + if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "swift", Namespace: instance.Namespace}, swift); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + if swift.Status.Conditions.IsTrue(swiftv1.SwiftProxyReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: swift.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Swift.Template.SwiftProxy.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + swift, + svcs, + instance.Spec.Swift.Template.SwiftProxy.Override.Service, + instance.Spec.Swift.ProxyOverride.Route, + corev1beta1.OpenStackControlPlaneExposeSwiftReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling Swift", "Swift.Namespace", instance.Namespace, "Swift.Name", "swift") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), swift, func() error { instance.Spec.Swift.Template.DeepCopyInto(&swift.Spec) + err := controllerutil.SetControllerReference(helper.GetBeforeObject(), swift, helper.GetScheme()) if err != nil { return err