From 1f42cbb59dbbcf93df6b14cc69324a3c56721d7c Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Thu, 27 Jul 2023 12:01:36 +0200 Subject: [PATCH 01/13] Create keystoneapi route and svc endpoint overrides Creates the route for the keystoneapi, 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 Jira: OSP-26690 --- ....openstack.org_openstackcontrolplanes.yaml | 1245 ++++++++++++----- apis/core/v1beta1/conditions.go | 15 +- .../v1beta1/openstackcontrolplane_types.go | 27 +- apis/core/v1beta1/zz_generated.deepcopy.go | 22 + apis/go.mod | 28 +- apis/go.sum | 56 +- ....openstack.org_openstackcontrolplanes.yaml | 1245 ++++++++++++----- ...nstack-operator.clusterserviceversion.yaml | 18 + config/rbac/role.yaml | 27 + ...controlplane_galera_network_isolation.yaml | 11 +- ...ne_galera_network_isolation_3replicas.yaml | 11 +- ...enstackcontrolplane_network_isolation.yaml | 11 +- ...ckcontrolplane_network_isolation_ceph.yaml | 11 +- .../core/openstackcontrolplane_controller.go | 11 +- go.mod | 32 +- go.sum | 56 +- main.go | 2 + pkg/openstack/common.go | 222 +++ pkg/openstack/keystone.go | 55 +- 19 files changed, 2324 insertions(+), 781 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index a4faf9a3a..0dc0abd34 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -124,32 +124,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -158,6 +132,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -1227,27 +1252,6 @@ spec: dnsDataLabelSelectorValue: default: dnsdata type: string - externalEndpoints: - items: - properties: - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - - loadBalancerIPs - type: object - type: array nodeSelector: additionalProperties: type: string @@ -1281,6 +1285,53 @@ spec: - values type: object type: array + override: + properties: + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -2893,32 +2944,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -2927,6 +2952,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object pvc: type: string replicas: @@ -2989,32 +3063,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -3023,6 +3071,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object pvc: type: string replicas: @@ -3166,6 +3263,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -3226,10 +3374,61 @@ spec: additionalProperties: type: string type: object - replicas: - default: 1 - format: int32 - maximum: 32 + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object + replicas: + default: 1 + format: int32 + maximum: 32 minimum: 0 type: integer resources: @@ -3399,6 +3598,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object preserveJobs: default: false type: boolean @@ -3439,20 +3687,6 @@ spec: x-kubernetes-int-or-string: true type: object type: object - route: - properties: - routeLocation: - type: string - routeName: - default: horizon - type: string - routeTLSCA: - type: string - routeTLSEnabled: - type: string - routeTLSKey: - type: string - type: object secret: type: string required: @@ -3929,6 +4163,107 @@ spec: type: object keystone: properties: + apiOverride: + 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 enabled: default: true type: boolean @@ -3965,32 +4300,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array memcachedInstance: default: memcached type: string @@ -4002,6 +4311,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: admin: AdminPassword @@ -4877,31 +5237,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -4910,6 +5245,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -5203,32 +5589,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array extraMounts: items: properties: @@ -5993,6 +6353,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: database: NeutronDatabasePassword @@ -6092,31 +6503,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -6125,6 +6511,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -6237,40 +6674,15 @@ spec: metadataServiceTemplate: properties: containerImage: - type: string - customServiceConfig: - type: string - defaultConfigOverwrite: - additionalProperties: - type: string - type: object - enabled: - type: boolean - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array + type: string + customServiceConfig: + type: string + defaultConfigOverwrite: + additionalProperties: + type: string + type: object + enabled: + type: boolean networkAttachments: items: type: string @@ -6279,6 +6691,53 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -6329,31 +6788,6 @@ spec: type: object enabled: type: boolean - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -6362,6 +6796,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -6455,31 +6938,6 @@ spec: type: object enabled: type: boolean - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -6488,6 +6946,53 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -7021,32 +7526,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -7055,6 +7534,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: database: PlacementDatabasePassword @@ -7493,6 +8023,12 @@ spec: type: object externalEndpoint: properties: + endpoint: + default: internal + enum: + - internal + - public + type: string ipAddressPool: minLength: 1 type: string @@ -11202,6 +11738,57 @@ spec: type: string containerImageProxy: type: string + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: service: SwiftPassword diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index c1f4ae512..36ab3d804 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -33,6 +33,9 @@ const ( // OpenStackControlPlaneKeystoneAPIReadyCondition Status=True condition which indicates if KeystoneAPI is configured and operational OpenStackControlPlaneKeystoneAPIReadyCondition condition.Type = "OpenStackControlPlaneKeystoneAPIReady" + // OpenStackControlPlaneExposeKeystoneAPIReadyCondition Status=True condition which indicates if KeystoneAPI is exposed via a route + OpenStackControlPlaneExposeKeystoneAPIReadyCondition condition.Type = "OpenStackControlPlaneExposeKeystoneAPIReady" + // OpenStackControlPlanePlacementAPIReadyCondition Status=True condition which indicates if PlacementAPI is configured and operational OpenStackControlPlanePlacementAPIReadyCondition condition.Type = "OpenStackControlPlanePlacementAPIReady" @@ -75,6 +78,9 @@ const ( // OpenStackControlPlaneCeilometerReadyCondition Status=True condition which indicates if OpenStack Ceilometer service is configured and operational OpenStackControlPlaneCeilometerReadyCondition condition.Type = "OpenStackControlPlaneCeilometerReady" + // OpenStackControlPlaneServiceOverrideReadyCondition Status=True condition which indicates if OpenStack service override has created ok + OpenStackControlPlaneServiceOverrideReadyCondition condition.Type = "OpenStackControlPlaneServiceOverrideReady" + // OpenStackControlPlaneManilaReadyInitMessage OpenStackControlPlaneManilaReadyInitMessage = "OpenStackControlPlane Manila not started" @@ -107,7 +113,6 @@ const ( // OpenStackControlPlaneRedisReadyCondition Status=True condition which indicates if Redis is configured and operational OpenStackControlPlaneRedisReadyCondition condition.Type = "OpenStackControlPlaneRedisReady" - ) // OpenStackControlPlane Reasons used by API objects. @@ -338,4 +343,12 @@ const ( // OpenStackControlPlaneRedisReadyErrorMessage OpenStackControlPlaneRedisReadyErrorMessage = "OpenStackControlPlane Redis error occured %s" + // OpenStackControlPlaneExposeServiceReadyInitMessage + OpenStackControlPlaneExposeServiceReadyInitMessage = "OpenStackControlPlane %s exposing service %s not started" + + // OpenStackControlPlaneExposeServiceReadyErrorMessage + OpenStackControlPlaneExposeServiceReadyErrorMessage = "OpenStackControlPlane %s exposing service via route %s error occured %s" + + // OpenStackControlPlaneExposeServiceReadyMessage + OpenStackControlPlaneExposeServiceReadyMessage = "OpenStackControlPlane %s service exposed" ) diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 7349a5ee8..4e32e5b26 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -23,22 +23,24 @@ import ( horizonv1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1" memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" networkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" + redisv1 "github.com/openstack-k8s-operators/infra-operator/apis/redis/v1beta1" ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1" keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/route" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/util" "github.com/openstack-k8s-operators/lib-common/modules/storage" manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" + octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" ovnv1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" placementv1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1" swiftv1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" telemetryv1 "github.com/openstack-k8s-operators/telemetry-operator/api/v1beta1" rabbitmqv1 "github.com/rabbitmq/cluster-operator/api/v1beta1" - redisv1 "github.com/openstack-k8s-operators/infra-operator/apis/redis/v1beta1" - octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -190,9 +192,21 @@ type KeystoneSection struct { Enabled bool `json:"enabled"` // +kubebuilder:validation:Optional - //+operator-sdk:csv:customresourcedefinitions:type=spec + // +operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Keystone service Template keystonev1.KeystoneAPISpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` +} + +// Override to override the generated manifest of several child resources. +type Override struct { + // +kubebuilder:validation:Optional + // Route overrides to use when creating the public service endpoint + Route *route.OverrideSpec `json:"route,omitempty"` } // PlacementSection defines the desired state of Placement service @@ -308,6 +322,12 @@ type RabbitmqTemplate struct { // MetalLBConfig to configure the MetalLB loadbalancer service type MetalLBConfig struct { + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Enum=internal;public + // +kubebuilder:default=internal + // Endpoint, OpenStack endpoint this service maps to + Endpoint service.Endpoint `json:"endpoint"` + // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength=1 //+operator-sdk:csv:customresourcedefinitions:type=spec @@ -501,7 +521,6 @@ type RedisSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Templates - Overrides to use when creating the Redis Resources Templates map[string]redisv1.RedisSpec `json:"templates,omitempty"` - } // OpenStackControlPlaneStatus defines the observed state of OpenStackControlPlane diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index f04b9b9db..0c0d49b47 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -25,6 +25,7 @@ import ( memcachedv1beta1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" redisv1beta1 "github.com/openstack-k8s-operators/infra-operator/apis/redis/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/route" "github.com/openstack-k8s-operators/lib-common/modules/storage" apiv1beta1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" ovn_operatorapiv1beta1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" @@ -169,6 +170,7 @@ func (in *IronicSection) DeepCopy() *IronicSection { func (in *KeystoneSection) DeepCopyInto(out *KeystoneSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeystoneSection. @@ -476,6 +478,26 @@ func (in *OpenStackExtraVolMounts) DeepCopy() *OpenStackExtraVolMounts { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Override) DeepCopyInto(out *Override) { + *out = *in + if in.Route != nil { + in, out := &in.Route, &out.Route + *out = new(route.OverrideSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Override. +func (in *Override) DeepCopy() *Override { + if in == nil { + return nil + } + out := new(Override) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OvnResources) DeepCopyInto(out *OvnResources) { *out = *in diff --git a/apis/go.mod b/apis/go.mod index 1e3ed0d87..d963bc94b 100644 --- a/apis/go.mod +++ b/apis/go.mod @@ -5,22 +5,22 @@ go 1.19 require ( github.com/onsi/ginkgo/v2 v2.12.0 github.com/onsi/gomega v1.27.10 - github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230915101724-27ac1650268d - github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230918155018-15e9a91ab099 - github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230919010505-829b985599de - github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230919030438-b18e8fb1bcc8 - github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230918070031-70498d9b2fec + github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230921082510-1b9a7de3d088 + github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230921081203-89164087dac9 + github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230920142821-e84784bede25 + github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230920143411-511d89a0e6cc + github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230920125017-2c76cd203b44 github.com/openstack-k8s-operators/ironic-operator/api v0.1.1-0.20230915140049-df437872b34f - github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230918093932-0512e2f335dd - github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230918105853-7a32db095b3d - github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230916214930-2c2b11448ca0 + github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3 + github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 + github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230921081246-996d4e390998 github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230918111825-8999b3b2dc3c - github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230918064409-8ef2e76869c3 - github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230918133139-6bec6fb25b25 + github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230920145429-537b5afebd07 + github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230921152245-4a535c8f3e9a github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230915083637-79fc51fd4dcf github.com/openstack-k8s-operators/ovn-operator/api v0.1.1-0.20230913151226-aab30786ed97 - github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230918155857-7af4ec18350b - github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230915130355-e5c2b0ff0af1 + github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230920125340-3c99d09c7033 + github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230920144258-a37c476a2829 github.com/openstack-k8s-operators/telemetry-operator/api v0.1.1-0.20230922102555-fe2794ad1e8c github.com/rabbitmq/cluster-operator v1.14.0 k8s.io/apimachinery v0.26.9 @@ -65,8 +65,8 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openshift/api v3.9.0+incompatible // indirect - github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230918105853-7a32db095b3d //indirect - github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230918105853-7a32db095b3d + github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216 //indirect + github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230919113507-d74c2f31d216 github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect diff --git a/apis/go.sum b/apis/go.sum index 2fce3628a..ac9931a7e 100644 --- a/apis/go.sum +++ b/apis/go.sum @@ -128,42 +128,42 @@ github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxCMwNRnMjhhIDOWHJowi6q8G6koI= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= -github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230915101724-27ac1650268d h1:FJkVYIG6hUwSP7zGuSTVi5Tay3EH8d8h6aS5wVAYNw0= -github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230915101724-27ac1650268d/go.mod h1:ntpA98K0eWjVUe32OAogE5NUMXc+CsNeneIlYRaKjd8= -github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230918155018-15e9a91ab099 h1:+B8EqaMrG6zPmH6YkAzA/UsTvlMUtNBPvoZHoibKDUs= -github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230918155018-15e9a91ab099/go.mod h1:EyWZbdyzJM2hEz1dDDo87oQic1HGUdi46vAtH6Y7DnU= -github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230919010505-829b985599de h1:c9AgISgzQLwxfb3WEuDVWfNvu0eVywsA/wDFlEFL77k= -github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230919010505-829b985599de/go.mod h1:cYYINAv7b89hsSvyzsDD5FEN4X0hC0J6tKomTxVrcTo= -github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230919030438-b18e8fb1bcc8 h1:mqZ6oKNoS7ym9xCIDZ43FbUQWpo7zZI52XLh4hMPM44= -github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230919030438-b18e8fb1bcc8/go.mod h1:brUv4XGvLPITO6Tn4fXTk6s4Ts/VMwDuFiypC2xclOc= -github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230918070031-70498d9b2fec h1:+8EYd1O5SO0wadEc8EYwTI0AdtCOxaAfg/dfS+rq5jM= -github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230918070031-70498d9b2fec/go.mod h1:G4vJpe0Hr2s1U+tjN8m7Rd9vUIdnwPBJJbjA/r+Dnjw= +github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230921082510-1b9a7de3d088 h1:FCEsDNLC9yrHHgjbyKor2dwdA1bQ5g4c7ZY/6wLULZY= +github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230921082510-1b9a7de3d088/go.mod h1:72cIiRrj5BcJqtYFQy+fz53Wz/AeLoivIwUO42Ae/aY= +github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230921081203-89164087dac9 h1:KZfGSL/68+wK4jOqbGYtUtPOuQ8TVVO+YPM96Rxm70Y= +github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230921081203-89164087dac9/go.mod h1:JTRoxU5lUkkEQlwwokxw9L52imeneRujRYUrPkdZjC0= +github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230920142821-e84784bede25 h1:DjZyZo2XoWZuZmXVU+P7RGFomVbfDosQuXR8AumN9ss= +github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230920142821-e84784bede25/go.mod h1:O1GPo8nmJ2yM5+xH89M4L9YiMkEAXHE160+tA6d0H+s= +github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230920143411-511d89a0e6cc h1:Y4+0OX8areIATKd/7izNFC2U8PCXZWLWfKhQN79hCyk= +github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230920143411-511d89a0e6cc/go.mod h1:rFtiDTgkoNa+Z+F0q87SIRINWm6gbgeaK3Uyl3bl/Tg= +github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230920125017-2c76cd203b44 h1:W2HZy+uk5fnVwvw3+/Jd/k7sNiVXCOd8SiV0dMvmjys= +github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230920125017-2c76cd203b44/go.mod h1:fOJ95wMSymtfoellY/TFKcrzW6bu/nTCTzEnFEgCGCc= github.com/openstack-k8s-operators/ironic-operator/api v0.1.1-0.20230915140049-df437872b34f h1:dDlJMlhvM6csW24Tf3X8SEW3rG2k08SBgV0ORR1Ts6w= github.com/openstack-k8s-operators/ironic-operator/api v0.1.1-0.20230915140049-df437872b34f/go.mod h1:51ig7IbGf7AjxeWi7+qvmRp0C5lp91e+HhXYTYlhVng= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230918093932-0512e2f335dd h1:pCYr/sI5oUA45Ff/tHsQQdKmmU4UoVbyCguJNKGXhHw= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230918093932-0512e2f335dd/go.mod h1:98HNU3wP40DHFI7YBr9nNjf2BdbcdUXlyyIg4odYo68= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230918105853-7a32db095b3d h1:TPj8NdoftSWVT95K8JNAYCQLFYk0pvC2OHxhxgleeks= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230918105853-7a32db095b3d/go.mod h1:Ge7Yf6AUmjEvJK9AIW2bT5udLzBIcK59b1QxqymncaQ= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230918105853-7a32db095b3d h1:bbVgdhw3heFSSVsxjUHROvNrYaydcW0SbhsHBgUY/JE= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230918105853-7a32db095b3d/go.mod h1:WP90lfGH3YBS0Ie23Yr9pfzoq2RbWYyg+thYQAgTFz8= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230918105853-7a32db095b3d h1:cPvHbA/N7/zDUgAVxqNBs+7puYMYHGNu11tvgDEK4ys= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230918105853-7a32db095b3d/go.mod h1:DnsRBWOFEwecwrVAntM4lbgiHRvqfoz/gKYpDjkvCYE= -github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230916214930-2c2b11448ca0 h1:EME+DFx5uOLTr0WdtKTmtcEeLexL3MKdhfbQ3YHPlmo= -github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230916214930-2c2b11448ca0/go.mod h1:ql5AXzavvd29nkvPejuEmfFGyFrwGoAd0ARLzx0dz5c= +github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3 h1:6VCz/ZBTJEQJTx4+z8UxLv3WITa4Bgx5CSP237wJ5xM= +github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3/go.mod h1:ta6w/29i4WuWkQp6I4cOLwMGQ5/vJI0y8Em7u+M34jo= +github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 h1:arYbQA6bLyXJkHm+6M6gPc4YpWMFjs5qkG16Yii4UDo= +github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:Ge7Yf6AUmjEvJK9AIW2bT5udLzBIcK59b1QxqymncaQ= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216 h1:h76faqi4WAXBs3D2B0GLUdlCjS0dh78wRL0d5RZUwhk= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:GHi64tgyC75/vuT8Crda0yN5iCIYiSyS4bpzYJjX7MA= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230919113507-d74c2f31d216 h1:1dMwzjuZJSRgHcwblOo6jHrWAe2anwWu4w35Rukz1kw= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:DnsRBWOFEwecwrVAntM4lbgiHRvqfoz/gKYpDjkvCYE= +github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230921081246-996d4e390998 h1:BAxLz7+Bqz0M6INK4xDcod9cB2idOjRYyoPHqIySqK8= +github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230921081246-996d4e390998/go.mod h1:7nnls/xwOqOQWFZ84Orif2UQcWTdN32Xqd56y9TBhYI= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230918111825-8999b3b2dc3c h1:9R8T1WRwuPS5KMfsQWxAMSGPuJrGMJ7bODKK9dirhHA= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230918111825-8999b3b2dc3c/go.mod h1:xXHF/R/L0XamRHR/UkzlgzSTocBQ6GSQ2U16Q9Mf/bA= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230918064409-8ef2e76869c3 h1:j3cxYPlXlmFqSD5jYNnHxfjrKb8SD8ZqgkgB//h8dVk= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230918064409-8ef2e76869c3/go.mod h1:hn/5cDgN+hvPlNPZ6e6SIFo5wrjntg+3uGHny7WrrZs= -github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230918133139-6bec6fb25b25 h1:8PmVQMua8538u3M13Q1BGttKQ0vs/p/G94bBqRCfjxA= -github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230918133139-6bec6fb25b25/go.mod h1:FiLYIHuPP1nzEvf/03QG0DGBDXQsQU0OAuGDLxPcJDo= +github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230920145429-537b5afebd07 h1:jCfKZN9smTbdCbfOgDxa1JCzsrgNsO8fyZjikEArugo= +github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230920145429-537b5afebd07/go.mod h1:gyme//YzQKEWSn3i3S0oaNBjnMu/m2m0N13boSShBfE= +github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230921152245-4a535c8f3e9a h1:yBEEaxtR4RWH/M9dAHUQPJ/TBbFDiRkQB4YJcKCcqGE= +github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230921152245-4a535c8f3e9a/go.mod h1:kyi9gsAg4d8hxjUxnjDTMZeps3xTutH2+FcAnz783m8= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230915083637-79fc51fd4dcf h1:e6peuUus9UjB8qpVH0MAUpwog7pHgSAH80cYpaLVKvU= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230915083637-79fc51fd4dcf/go.mod h1:r8xZ27TZ5EPgH+EL6VRQRv0tIxlu0zNNvTnz9PjjZUg= github.com/openstack-k8s-operators/ovn-operator/api v0.1.1-0.20230913151226-aab30786ed97 h1:+nrBob4GwmRqhISqPiP7lhMwys2kJz1vYmLzKap+B7E= github.com/openstack-k8s-operators/ovn-operator/api v0.1.1-0.20230913151226-aab30786ed97/go.mod h1:0zpkMBsrFbFP+AfaJKvREHomqsXcPnUCOT0/LzKmga0= -github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230918155857-7af4ec18350b h1:nCpcDEKKVEYosNhmMpmmfDSdC3O8xGmBgpa9aLFcaTM= -github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230918155857-7af4ec18350b/go.mod h1:lsu2XlR/HbYoiUrRPBDbXLBoD+omzhK9zBSk4QJppmU= -github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230915130355-e5c2b0ff0af1 h1:MI+1sJuo+2ekYB/npq9BqMR0Ix03hpRXFOW5NGvL6Zo= -github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230915130355-e5c2b0ff0af1/go.mod h1:jnhL2sWJW7ABY/mQ0Mp95h0aJR6oh90/rgDINg3Sg88= +github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230920125340-3c99d09c7033 h1:/oIWCEllgIXQbjIj6i8NFK3yC5IHkflnMDSmdz2PeCs= +github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230920125340-3c99d09c7033/go.mod h1:gJmnk2QLICVEZXi2wDpr+baNMvey7RA50gJbRXzo0JA= +github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230920144258-a37c476a2829 h1:rUjN/Dfcxw7mqCQhc/BZw/cl4u9keuQsM4KhvMIDLaE= +github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230920144258-a37c476a2829/go.mod h1:YWvPPQwcCRfw5zaFp4KTdBKBiLt1h00LUMcnPkVSNVw= github.com/openstack-k8s-operators/telemetry-operator/api v0.1.1-0.20230922102555-fe2794ad1e8c h1:lb1CxMumTtKvmIAFVw5CBSXwg90lkeAfj5jk1ycYXio= github.com/openstack-k8s-operators/telemetry-operator/api v0.1.1-0.20230922102555-fe2794ad1e8c/go.mod h1:nYAEI/2u2DzXtZoMBIRkogHPpjskwrfJAJ/+XeIcosc= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index a4faf9a3a..0dc0abd34 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -124,32 +124,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -158,6 +132,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -1227,27 +1252,6 @@ spec: dnsDataLabelSelectorValue: default: dnsdata type: string - externalEndpoints: - items: - properties: - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - - loadBalancerIPs - type: object - type: array nodeSelector: additionalProperties: type: string @@ -1281,6 +1285,53 @@ spec: - values type: object type: array + override: + properties: + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -2893,32 +2944,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -2927,6 +2952,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object pvc: type: string replicas: @@ -2989,32 +3063,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -3023,6 +3071,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object pvc: type: string replicas: @@ -3166,6 +3263,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -3226,10 +3374,61 @@ spec: additionalProperties: type: string type: object - replicas: - default: 1 - format: int32 - maximum: 32 + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object + replicas: + default: 1 + format: int32 + maximum: 32 minimum: 0 type: integer resources: @@ -3399,6 +3598,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object preserveJobs: default: false type: boolean @@ -3439,20 +3687,6 @@ spec: x-kubernetes-int-or-string: true type: object type: object - route: - properties: - routeLocation: - type: string - routeName: - default: horizon - type: string - routeTLSCA: - type: string - routeTLSEnabled: - type: string - routeTLSKey: - type: string - type: object secret: type: string required: @@ -3929,6 +4163,107 @@ spec: type: object keystone: properties: + apiOverride: + 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 enabled: default: true type: boolean @@ -3965,32 +4300,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array memcachedInstance: default: memcached type: string @@ -4002,6 +4311,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: admin: AdminPassword @@ -4877,31 +5237,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -4910,6 +5245,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -5203,32 +5589,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array extraMounts: items: properties: @@ -5993,6 +6353,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: database: NeutronDatabasePassword @@ -6092,31 +6503,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -6125,6 +6511,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -6237,40 +6674,15 @@ spec: metadataServiceTemplate: properties: containerImage: - type: string - customServiceConfig: - type: string - defaultConfigOverwrite: - additionalProperties: - type: string - type: object - enabled: - type: boolean - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array + type: string + customServiceConfig: + type: string + defaultConfigOverwrite: + additionalProperties: + type: string + type: object + enabled: + type: boolean networkAttachments: items: type: string @@ -6279,6 +6691,53 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -6329,31 +6788,6 @@ spec: type: object enabled: type: boolean - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -6362,6 +6796,55 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -6455,31 +6938,6 @@ spec: type: object enabled: type: boolean - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -6488,6 +6946,53 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -7021,32 +7526,6 @@ spec: additionalProperties: type: string type: object - externalEndpoints: - items: - properties: - endpoint: - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: items: type: string @@ -7055,6 +7534,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: database: PlacementDatabasePassword @@ -7493,6 +8023,12 @@ spec: type: object externalEndpoint: properties: + endpoint: + default: internal + enum: + - internal + - public + type: string ipAddressPool: minLength: 1 type: string @@ -11202,6 +11738,57 @@ spec: type: string containerImageProxy: type: string + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: service: SwiftPassword diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index 728fdb11f..68419222a 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -118,6 +118,24 @@ spec: path: keystone.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool + displayName: IPAddress Pool + path: keystone.externalEndpoints[0].ipAddressPool + - description: LoadBalancerIPs, request given IPs from the pool if available. + Using a list to allow dual stack (IPv4/IPv6) support + displayName: Load Balancer IPs + path: keystone.externalEndpoints[0].loadBalancerIPs + - description: SharedIP if true, VIP/VIPs get shared with multiple services + displayName: Shared IP + path: keystone.externalEndpoints[0].sharedIP + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: SharedIPKey specifies the sharing key which gets set as the annotation + on the LoadBalancer service. Services which share the same VIP must have + the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, + but no SharedIPKey specified. + displayName: Shared IPKey + path: keystone.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating the Keystone service displayName: Template path: keystone.template diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 1da890265..6c13715fa 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -81,6 +81,13 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list - apiGroups: - core.openstack.org resources: @@ -355,6 +362,26 @@ rules: - patch - update - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - route.openshift.io + resources: + - routes/custom-host + verbs: + - create + - patch + - update - apiGroups: - security.openshift.io resourceNames: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 9c3369b72..52ec6ca86 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -82,14 +82,9 @@ spec: networkAttachments: - storage keystone: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -100,6 +95,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret mariadb: enabled: false templates: 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 42e1b9f21..f564e8981 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -82,14 +82,9 @@ spec: networkAttachments: - storage keystone: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -100,6 +95,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret mariadb: enabled: false templates: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 19a218afa..3c04363cf 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -82,14 +82,9 @@ spec: networkAttachments: - storage keystone: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -100,6 +95,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret mariadb: templates: openstack: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index 10d6d819d..beffb0a10 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -127,14 +127,9 @@ spec: networkAttachments: - storage keystone: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -145,6 +140,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret mariadb: templates: openstack: diff --git a/controllers/core/openstackcontrolplane_controller.go b/controllers/core/openstackcontrolplane_controller.go index 3758d7803..358efac33 100644 --- a/controllers/core/openstackcontrolplane_controller.go +++ b/controllers/core/openstackcontrolplane_controller.go @@ -20,6 +20,7 @@ import ( "context" "fmt" + routev1 "github.com/openshift/api/route/v1" cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" glancev1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1" heatv1 "github.com/openstack-k8s-operators/heat-operator/api/v1beta1" @@ -30,13 +31,16 @@ import ( keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + "github.com/openstack-k8s-operators/openstack-operator/pkg/openstack" + ovnv1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" placementv1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1" swiftv1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" @@ -87,6 +91,9 @@ type OpenStackControlPlaneReconciler struct { //+kubebuilder:rbac:groups=swift.openstack.org,resources=swifts,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=octavia.openstack.org,resources=octavias,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=redis.openstack.org,resources=redises,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete; +//+kubebuilder:rbac:groups=route.openshift.io,resources=routes/custom-host,verbs=create;update;patch +//+kubebuilder:rbac:groups=core,resources=services,verbs=get;list; // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -152,9 +159,6 @@ func (r *OpenStackControlPlaneReconciler) Reconcile(ctx context.Context, req ctr return ctrl.Result{}, nil } - // Reset all ReadyConditons to 'Unknown' - instance.InitConditions() - return r.reconcileNormal(ctx, instance, helper) } @@ -335,5 +339,6 @@ func (r *OpenStackControlPlaneReconciler) SetupWithManager(mgr ctrl.Manager) err Owns(&telemetryv1.Ceilometer{}). Owns(&redisv1.Redis{}). Owns(&octaviav1.Octavia{}). + Owns(&routev1.Route{}). Complete(r) } diff --git a/go.mod b/go.mod index 2016b42b0..1f2023403 100644 --- a/go.mod +++ b/go.mod @@ -8,26 +8,26 @@ require ( github.com/imdario/mergo v0.3.16 github.com/onsi/ginkgo/v2 v2.12.0 github.com/onsi/gomega v1.27.10 - github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230915101724-27ac1650268d + github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230921082510-1b9a7de3d088 github.com/openstack-k8s-operators/dataplane-operator/api v0.1.1-0.20230919085012-e89d5ef2fafd - github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230918155018-15e9a91ab099 - github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230919010505-829b985599de - github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230919030438-b18e8fb1bcc8 - github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230918070031-70498d9b2fec + github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230921081203-89164087dac9 + github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230920142821-e84784bede25 + github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230920143411-511d89a0e6cc + github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230920125017-2c76cd203b44 github.com/openstack-k8s-operators/ironic-operator/api v0.1.1-0.20230915140049-df437872b34f - github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230918093932-0512e2f335dd - github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230918105853-7a32db095b3d - github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230916214930-2c2b11448ca0 + github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3 + github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 + github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230921081246-996d4e390998 github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230918111825-8999b3b2dc3c - github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230918064409-8ef2e76869c3 - github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230918133139-6bec6fb25b25 + github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230920145429-537b5afebd07 + github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230921152245-4a535c8f3e9a github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230915083637-79fc51fd4dcf github.com/openstack-k8s-operators/openstack-ansibleee-operator/api v0.1.1-0.20230918170038-6c1275780727 github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.1.1-0.20230915055858-ecb378f804c9 github.com/openstack-k8s-operators/openstack-operator/apis v0.0.0-20230725141229-4ce90d0120fd github.com/openstack-k8s-operators/ovn-operator/api v0.1.1-0.20230913151226-aab30786ed97 - github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230918155857-7af4ec18350b - github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230915130355-e5c2b0ff0af1 + github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230920125340-3c99d09c7033 + github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230920144258-a37c476a2829 github.com/openstack-k8s-operators/telemetry-operator/api v0.1.1-0.20230922102555-fe2794ad1e8c github.com/operator-framework/api v0.17.3 github.com/rabbitmq/cluster-operator v1.14.0 @@ -74,9 +74,9 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/openshift/api v3.9.0+incompatible // indirect - github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230918105853-7a32db095b3d //indirect - github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230918105853-7a32db095b3d //indirect + github.com/openshift/api v3.9.0+incompatible + github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216 //indirect + github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230919113507-d74c2f31d216 //indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect @@ -101,7 +101,7 @@ require ( k8s.io/component-base v0.26.9 //indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 //indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b //indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd //indirect sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/go.sum b/go.sum index 5f63e64ef..2a07fd383 100644 --- a/go.sum +++ b/go.sum @@ -135,36 +135,36 @@ github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxCMwNRnMjhhIDOWHJowi6q8G6koI= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= -github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230915101724-27ac1650268d h1:FJkVYIG6hUwSP7zGuSTVi5Tay3EH8d8h6aS5wVAYNw0= -github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230915101724-27ac1650268d/go.mod h1:ntpA98K0eWjVUe32OAogE5NUMXc+CsNeneIlYRaKjd8= +github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230921082510-1b9a7de3d088 h1:FCEsDNLC9yrHHgjbyKor2dwdA1bQ5g4c7ZY/6wLULZY= +github.com/openstack-k8s-operators/cinder-operator/api v0.1.2-0.20230921082510-1b9a7de3d088/go.mod h1:72cIiRrj5BcJqtYFQy+fz53Wz/AeLoivIwUO42Ae/aY= github.com/openstack-k8s-operators/dataplane-operator/api v0.1.1-0.20230919085012-e89d5ef2fafd h1:R2TWVLgY7M784L50hz3oVV4ITpNKBCTQjXNH2gwIkNM= github.com/openstack-k8s-operators/dataplane-operator/api v0.1.1-0.20230919085012-e89d5ef2fafd/go.mod h1:LnS0qiX6PvruiLuObi5jub8sbJ4XkMCjHPLak1uNXuQ= -github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230918155018-15e9a91ab099 h1:+B8EqaMrG6zPmH6YkAzA/UsTvlMUtNBPvoZHoibKDUs= -github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230918155018-15e9a91ab099/go.mod h1:EyWZbdyzJM2hEz1dDDo87oQic1HGUdi46vAtH6Y7DnU= -github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230919010505-829b985599de h1:c9AgISgzQLwxfb3WEuDVWfNvu0eVywsA/wDFlEFL77k= -github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230919010505-829b985599de/go.mod h1:cYYINAv7b89hsSvyzsDD5FEN4X0hC0J6tKomTxVrcTo= -github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230919030438-b18e8fb1bcc8 h1:mqZ6oKNoS7ym9xCIDZ43FbUQWpo7zZI52XLh4hMPM44= -github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230919030438-b18e8fb1bcc8/go.mod h1:brUv4XGvLPITO6Tn4fXTk6s4Ts/VMwDuFiypC2xclOc= -github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230918070031-70498d9b2fec h1:+8EYd1O5SO0wadEc8EYwTI0AdtCOxaAfg/dfS+rq5jM= -github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230918070031-70498d9b2fec/go.mod h1:G4vJpe0Hr2s1U+tjN8m7Rd9vUIdnwPBJJbjA/r+Dnjw= +github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230921081203-89164087dac9 h1:KZfGSL/68+wK4jOqbGYtUtPOuQ8TVVO+YPM96Rxm70Y= +github.com/openstack-k8s-operators/glance-operator/api v0.1.2-0.20230921081203-89164087dac9/go.mod h1:JTRoxU5lUkkEQlwwokxw9L52imeneRujRYUrPkdZjC0= +github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230920142821-e84784bede25 h1:DjZyZo2XoWZuZmXVU+P7RGFomVbfDosQuXR8AumN9ss= +github.com/openstack-k8s-operators/heat-operator/api v0.1.1-0.20230920142821-e84784bede25/go.mod h1:O1GPo8nmJ2yM5+xH89M4L9YiMkEAXHE160+tA6d0H+s= +github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230920143411-511d89a0e6cc h1:Y4+0OX8areIATKd/7izNFC2U8PCXZWLWfKhQN79hCyk= +github.com/openstack-k8s-operators/horizon-operator/api v0.1.1-0.20230920143411-511d89a0e6cc/go.mod h1:rFtiDTgkoNa+Z+F0q87SIRINWm6gbgeaK3Uyl3bl/Tg= +github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230920125017-2c76cd203b44 h1:W2HZy+uk5fnVwvw3+/Jd/k7sNiVXCOd8SiV0dMvmjys= +github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230920125017-2c76cd203b44/go.mod h1:fOJ95wMSymtfoellY/TFKcrzW6bu/nTCTzEnFEgCGCc= github.com/openstack-k8s-operators/ironic-operator/api v0.1.1-0.20230915140049-df437872b34f h1:dDlJMlhvM6csW24Tf3X8SEW3rG2k08SBgV0ORR1Ts6w= github.com/openstack-k8s-operators/ironic-operator/api v0.1.1-0.20230915140049-df437872b34f/go.mod h1:51ig7IbGf7AjxeWi7+qvmRp0C5lp91e+HhXYTYlhVng= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230918093932-0512e2f335dd h1:pCYr/sI5oUA45Ff/tHsQQdKmmU4UoVbyCguJNKGXhHw= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230918093932-0512e2f335dd/go.mod h1:98HNU3wP40DHFI7YBr9nNjf2BdbcdUXlyyIg4odYo68= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230918105853-7a32db095b3d h1:TPj8NdoftSWVT95K8JNAYCQLFYk0pvC2OHxhxgleeks= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230918105853-7a32db095b3d/go.mod h1:Ge7Yf6AUmjEvJK9AIW2bT5udLzBIcK59b1QxqymncaQ= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230918105853-7a32db095b3d h1:bbVgdhw3heFSSVsxjUHROvNrYaydcW0SbhsHBgUY/JE= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230918105853-7a32db095b3d/go.mod h1:WP90lfGH3YBS0Ie23Yr9pfzoq2RbWYyg+thYQAgTFz8= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230918105853-7a32db095b3d h1:cPvHbA/N7/zDUgAVxqNBs+7puYMYHGNu11tvgDEK4ys= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230918105853-7a32db095b3d/go.mod h1:DnsRBWOFEwecwrVAntM4lbgiHRvqfoz/gKYpDjkvCYE= -github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230916214930-2c2b11448ca0 h1:EME+DFx5uOLTr0WdtKTmtcEeLexL3MKdhfbQ3YHPlmo= -github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230916214930-2c2b11448ca0/go.mod h1:ql5AXzavvd29nkvPejuEmfFGyFrwGoAd0ARLzx0dz5c= +github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3 h1:6VCz/ZBTJEQJTx4+z8UxLv3WITa4Bgx5CSP237wJ5xM= +github.com/openstack-k8s-operators/keystone-operator/api v0.1.1-0.20230920085319-92ae0260bbf3/go.mod h1:ta6w/29i4WuWkQp6I4cOLwMGQ5/vJI0y8Em7u+M34jo= +github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 h1:arYbQA6bLyXJkHm+6M6gPc4YpWMFjs5qkG16Yii4UDo= +github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:Ge7Yf6AUmjEvJK9AIW2bT5udLzBIcK59b1QxqymncaQ= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216 h1:h76faqi4WAXBs3D2B0GLUdlCjS0dh78wRL0d5RZUwhk= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:GHi64tgyC75/vuT8Crda0yN5iCIYiSyS4bpzYJjX7MA= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230919113507-d74c2f31d216 h1:1dMwzjuZJSRgHcwblOo6jHrWAe2anwWu4w35Rukz1kw= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.1-0.20230919113507-d74c2f31d216/go.mod h1:DnsRBWOFEwecwrVAntM4lbgiHRvqfoz/gKYpDjkvCYE= +github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230921081246-996d4e390998 h1:BAxLz7+Bqz0M6INK4xDcod9cB2idOjRYyoPHqIySqK8= +github.com/openstack-k8s-operators/manila-operator/api v0.1.1-0.20230921081246-996d4e390998/go.mod h1:7nnls/xwOqOQWFZ84Orif2UQcWTdN32Xqd56y9TBhYI= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230918111825-8999b3b2dc3c h1:9R8T1WRwuPS5KMfsQWxAMSGPuJrGMJ7bODKK9dirhHA= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.1-0.20230918111825-8999b3b2dc3c/go.mod h1:xXHF/R/L0XamRHR/UkzlgzSTocBQ6GSQ2U16Q9Mf/bA= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230918064409-8ef2e76869c3 h1:j3cxYPlXlmFqSD5jYNnHxfjrKb8SD8ZqgkgB//h8dVk= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230918064409-8ef2e76869c3/go.mod h1:hn/5cDgN+hvPlNPZ6e6SIFo5wrjntg+3uGHny7WrrZs= -github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230918133139-6bec6fb25b25 h1:8PmVQMua8538u3M13Q1BGttKQ0vs/p/G94bBqRCfjxA= -github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230918133139-6bec6fb25b25/go.mod h1:FiLYIHuPP1nzEvf/03QG0DGBDXQsQU0OAuGDLxPcJDo= +github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230920145429-537b5afebd07 h1:jCfKZN9smTbdCbfOgDxa1JCzsrgNsO8fyZjikEArugo= +github.com/openstack-k8s-operators/neutron-operator/api v0.1.1-0.20230920145429-537b5afebd07/go.mod h1:gyme//YzQKEWSn3i3S0oaNBjnMu/m2m0N13boSShBfE= +github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230921152245-4a535c8f3e9a h1:yBEEaxtR4RWH/M9dAHUQPJ/TBbFDiRkQB4YJcKCcqGE= +github.com/openstack-k8s-operators/nova-operator/api v0.1.2-0.20230921152245-4a535c8f3e9a/go.mod h1:kyi9gsAg4d8hxjUxnjDTMZeps3xTutH2+FcAnz783m8= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230915083637-79fc51fd4dcf h1:e6peuUus9UjB8qpVH0MAUpwog7pHgSAH80cYpaLVKvU= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230915083637-79fc51fd4dcf/go.mod h1:r8xZ27TZ5EPgH+EL6VRQRv0tIxlu0zNNvTnz9PjjZUg= github.com/openstack-k8s-operators/openstack-ansibleee-operator/api v0.1.1-0.20230918170038-6c1275780727 h1:D/FWfsLEWNvIBxXRzJmQmzmwp/jZuap3JNicVWo5Eh4= @@ -173,10 +173,10 @@ github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.1.1-0.202 github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.1.1-0.20230915055858-ecb378f804c9/go.mod h1:9cWHjNK7MyiWxCx9779Mcieal5N0NLn75yraIlTuI2s= github.com/openstack-k8s-operators/ovn-operator/api v0.1.1-0.20230913151226-aab30786ed97 h1:+nrBob4GwmRqhISqPiP7lhMwys2kJz1vYmLzKap+B7E= github.com/openstack-k8s-operators/ovn-operator/api v0.1.1-0.20230913151226-aab30786ed97/go.mod h1:0zpkMBsrFbFP+AfaJKvREHomqsXcPnUCOT0/LzKmga0= -github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230918155857-7af4ec18350b h1:nCpcDEKKVEYosNhmMpmmfDSdC3O8xGmBgpa9aLFcaTM= -github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230918155857-7af4ec18350b/go.mod h1:lsu2XlR/HbYoiUrRPBDbXLBoD+omzhK9zBSk4QJppmU= -github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230915130355-e5c2b0ff0af1 h1:MI+1sJuo+2ekYB/npq9BqMR0Ix03hpRXFOW5NGvL6Zo= -github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230915130355-e5c2b0ff0af1/go.mod h1:jnhL2sWJW7ABY/mQ0Mp95h0aJR6oh90/rgDINg3Sg88= +github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230920125340-3c99d09c7033 h1:/oIWCEllgIXQbjIj6i8NFK3yC5IHkflnMDSmdz2PeCs= +github.com/openstack-k8s-operators/placement-operator/api v0.1.1-0.20230920125340-3c99d09c7033/go.mod h1:gJmnk2QLICVEZXi2wDpr+baNMvey7RA50gJbRXzo0JA= +github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230920144258-a37c476a2829 h1:rUjN/Dfcxw7mqCQhc/BZw/cl4u9keuQsM4KhvMIDLaE= +github.com/openstack-k8s-operators/swift-operator/api v0.1.1-0.20230920144258-a37c476a2829/go.mod h1:YWvPPQwcCRfw5zaFp4KTdBKBiLt1h00LUMcnPkVSNVw= github.com/openstack-k8s-operators/telemetry-operator/api v0.1.1-0.20230922102555-fe2794ad1e8c h1:lb1CxMumTtKvmIAFVw5CBSXwg90lkeAfj5jk1ycYXio= github.com/openstack-k8s-operators/telemetry-operator/api v0.1.1-0.20230922102555-fe2794ad1e8c/go.mod h1:nYAEI/2u2DzXtZoMBIRkogHPpjskwrfJAJ/+XeIcosc= github.com/operator-framework/api v0.17.3 h1:wddE1SLKTNiIzwt28DbBIO+vPG2GOV6dkB9xBkDfT3o= diff --git a/main.go b/main.go index 94eb16767..059a24789 100644 --- a/main.go +++ b/main.go @@ -61,6 +61,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" + routev1 "github.com/openshift/api/route/v1" clientv1 "github.com/openstack-k8s-operators/openstack-operator/apis/client/v1beta1" corev1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" clientcontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/client" @@ -100,6 +101,7 @@ func init() { utilruntime.Must(swiftv1.AddToScheme(scheme)) utilruntime.Must(clientv1.AddToScheme(scheme)) utilruntime.Must(redisv1.AddToScheme(scheme)) + utilruntime.Must(routev1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/pkg/openstack/common.go b/pkg/openstack/common.go index 760a87c0a..b4f9c6ffb 100644 --- a/pkg/openstack/common.go +++ b/pkg/openstack/common.go @@ -2,9 +2,21 @@ package openstack import ( "context" + "fmt" + "time" + routev1 "github.com/openshift/api/route/v1" + "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/route" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" + "github.com/openstack-k8s-operators/lib-common/modules/common/util" + corev1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + k8s_corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -27,3 +39,213 @@ func EnsureDeleted(ctx context.Context, helper *helper.Helper, obj client.Object return ctrl.Result{}, nil } + +// AddServiceComponentLabel - adds component label to the service override to be able to query +// the service labels to check for any route creation +func AddServiceComponentLabel(svcOverride service.RoutedOverrideSpec, value string) service.RoutedOverrideSpec { + if svcOverride.EmbeddedLabelsAnnotations == nil { + svcOverride.EmbeddedLabelsAnnotations = &service.EmbeddedLabelsAnnotations{} + } + svcOverride.EmbeddedLabelsAnnotations.Labels = util.MergeStringMaps( + svcOverride.EmbeddedLabelsAnnotations.Labels, map[string]string{common.AppSelector: value}) + + return svcOverride +} + +// RouteDetails - route details +type RouteDetails struct { + RouteName string + Namespace string + Endpoint service.Endpoint + RouteOverrideSpec *route.OverrideSpec + ServiceLabel map[string]string + ServiceSpec *k8s_corev1.Service + endpointURL string + hostname *string + route *routev1.Route +} + +// GetRoutesListWithLabel - Get all routes in namespace of the obj matching label selector +func GetRoutesListWithLabel( + ctx context.Context, + h *helper.Helper, + namespace string, + labelSelectorMap map[string]string, +) (*routev1.RouteList, error) { + routeList := &routev1.RouteList{} + listOpts := []client.ListOption{ + client.InNamespace(namespace), + client.MatchingLabels(labelSelectorMap), + } + + if err := h.GetClient().List(ctx, routeList, listOpts...); err != nil { + err = fmt.Errorf("Error listing routes for %s: %w", labelSelectorMap, err) + return nil, err + } + + return routeList, nil +} + +// EnsureRoute - +func EnsureRoute( + ctx context.Context, + instance *corev1.OpenStackControlPlane, + helper *helper.Helper, + owner metav1.Object, + svcs *k8s_corev1.ServiceList, + svcOverrides map[service.Endpoint]service.RoutedOverrideSpec, + overrideSpec *route.OverrideSpec, + condType condition.Type, +) (map[service.Endpoint]service.RoutedOverrideSpec, ctrl.Result, error) { + + cleanCondition := true + + for _, svc := range svcs.Items { + rd := RouteDetails{ + RouteName: svc.Name, + Namespace: svc.Namespace, + Endpoint: service.Endpoint(svc.Annotations[service.AnnotationEndpointKey]), + RouteOverrideSpec: overrideSpec, + ServiceSpec: &svc, + } + svcOverride := svcOverrides[rd.Endpoint] + + // check if there is already a route with common.AppSelector from the service + if svcLabelVal, ok := svc.Labels[common.AppSelector]; ok { + routes, err := GetRoutesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: svcLabelVal}, + ) + if err != nil { + return svcOverrides, ctrl.Result{}, err + } + + // check the routes if name changed where we are the owner + for _, r := range routes.Items { + instanceRef := metav1.OwnerReference{ + APIVersion: instance.APIVersion, + Kind: instance.Kind, + Name: instance.GetName(), + UID: instance.GetUID(), + BlockOwnerDeletion: ptr.To(true), + Controller: ptr.To(true), + } + + owner := metav1.GetControllerOf(&r.ObjectMeta) + + // Delete the route if the service was changed not to expose a route + if svc.ObjectMeta.Annotations[service.AnnotationIngressCreateKey] == "false" && + r.Spec.To.Name == svc.Name && + owner != nil && owner.UID == instance.GetUID() { + // Delete any other owner refs from ref list to not block deletion until owners are gone + r.SetOwnerReferences([]metav1.OwnerReference{instanceRef}) + + // Delete route + err := helper.GetClient().Delete(ctx, &r) + if err != nil && !k8s_errors.IsNotFound(err) { + err = fmt.Errorf("Error deleting route %s: %w", r.Name, err) + return svcOverrides, ctrl.Result{}, err + } + + if svcOverride.EndpointURL != nil { + svcOverride.EndpointURL = nil + helper.GetLogger().Info(fmt.Sprintf("Service %s override endpointURL removed", svc.Name)) + } + } + } + } + + // If the service has the create ingress annotation and its a default ClusterIP service -> create route + if svc.ObjectMeta.Annotations[service.AnnotationIngressCreateKey] == "true" && svc.Spec.Type == k8s_corev1.ServiceTypeClusterIP { + if instance.Status.Conditions.Get(condType) == nil { + instance.Status.Conditions.Set(condition.UnknownCondition( + condType, + condition.InitReason, + corev1.OpenStackControlPlaneExposeServiceReadyInitMessage, + owner.GetName(), + svc.Name, + )) + } + + if svcOverride.EmbeddedLabelsAnnotations == nil { + svcOverride.EmbeddedLabelsAnnotations = &service.EmbeddedLabelsAnnotations{} + } + + if labelVal, ok := svcOverride.EmbeddedLabelsAnnotations.Labels[common.AppSelector]; ok { + rd.ServiceLabel = map[string]string{common.AppSelector: labelVal} + } + + ctrlResult, err := rd.CreateRoute(ctx, helper, owner) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condType, + condition.ErrorReason, + condition.SeverityWarning, + corev1.OpenStackControlPlaneExposeServiceReadyErrorMessage, + owner.GetName(), + rd.RouteName, + err.Error())) + + return svcOverrides, ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return svcOverrides, ctrlResult, nil + } + + cleanCondition = false + + // update override for the service with the route endpoint url + if rd.endpointURL != "" { + // Any trailing path will be added on the service-operator level. + svcOverride.EndpointURL = &rd.endpointURL + instance.Status.Conditions.MarkTrue(condType, corev1.OpenStackControlPlaneExposeServiceReadyMessage, owner.GetName()) + } + } + + svcOverrides[rd.Endpoint] = svcOverride + } + + if cleanCondition { + instance.Status.Conditions.Remove(condType) + } + + return svcOverrides, ctrl.Result{}, nil +} + +// CreateRoute - +func (rd *RouteDetails) CreateRoute( + ctx context.Context, + helper *helper.Helper, + owner metav1.Object, +) (ctrl.Result, error) { + // TODO TLS + route, err := route.NewRoute( + route.GenericRoute(&route.GenericRouteDetails{ + Name: rd.RouteName, + Namespace: rd.Namespace, + Labels: rd.ServiceLabel, + ServiceName: rd.ServiceSpec.Name, + TargetPortName: rd.ServiceSpec.Name, + }), + time.Duration(5)*time.Second, + rd.RouteOverrideSpec, + ) + if err != nil { + return ctrl.Result{}, err + } + route.OwnerReferences = append(route.OwnerReferences, owner) + + ctrlResult, err := route.CreateOrPatch(ctx, helper) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + rd.hostname = ptr.To(route.GetHostname()) + rd.endpointURL = "http://" + *rd.hostname + rd.route = route.GetRoute() + + return ctrl.Result{}, nil +} diff --git a/pkg/openstack/keystone.go b/pkg/openstack/keystone.go index b84846c9b..4aa507c12 100644 --- a/pkg/openstack/keystone.go +++ b/pkg/openstack/keystone.go @@ -4,14 +4,19 @@ 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" keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,12 +34,61 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneKeystoneAPIReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeKeystoneAPIReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Keystone.Template.Override.Service == nil { + instance.Spec.Keystone.Template.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Keystone.Template.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Keystone.Template.Override.Service[endpointType], + keystoneAPI.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: "keystone", Namespace: instance.Namespace}, keystoneAPI); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + if keystoneAPI.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: keystoneAPI.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Keystone.Template.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + keystoneAPI, + svcs, + instance.Spec.Keystone.Template.Override.Service, + instance.Spec.Keystone.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeKeystoneAPIReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling KeystoneAPI", "KeystoneAPI.Namespace", instance.Namespace, "KeystoneAPI.Name", "keystone") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), keystoneAPI, func() error { instance.Spec.Keystone.Template.DeepCopyInto(&keystoneAPI.Spec) + if keystoneAPI.Spec.Secret == "" { keystoneAPI.Spec.Secret = instance.Spec.Secret } @@ -76,5 +130,4 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo } return ctrl.Result{}, nil - } From 23ac8a6d5045e2030666edc06465f6d1c2d0bc17 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Tue, 1 Aug 2023 11:34:41 +0200 Subject: [PATCH 02/13] Create glanceapi route and svc endpoint overrides Creates the route for the glanceapi, 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/glance-operator/pull/285 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 ++++++++++++++++++ ...nstack-operator.clusterserviceversion.yaml | 18 ++++ ...controlplane_galera_network_isolation.yaml | 7 +- ...ne_galera_network_isolation_3replicas.yaml | 7 +- ...enstackcontrolplane_network_isolation.yaml | 7 +- ...ckcontrolplane_network_isolation_ceph.yaml | 7 +- pkg/openstack/glance.go | 61 ++++++++++- 11 files changed, 297 insertions(+), 21 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 0dc0abd34..3543548b7 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -2140,6 +2140,107 @@ spec: type: object glance: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 36ab3d804..7e60bf43d 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -42,6 +42,9 @@ const ( // OpenStackControlPlaneGlanceReadyCondition Status=True condition which indicates if Glance is configured and operational OpenStackControlPlaneGlanceReadyCondition condition.Type = "OpenStackControlPlaneGlanceReady" + // OpenStackControlPlaneExposeGlanceReadyCondition Status=True condition which indicates if Glance is exposed via a route + OpenStackControlPlaneExposeGlanceReadyCondition condition.Type = "OpenStackControlPlaneExposeGlanceReady" + // OpenStackControlPlaneCinderReadyCondition Status=True condition which indicates if Cinder is configured and operational OpenStackControlPlaneCinderReadyCondition condition.Type = "OpenStackControlPlaneCinderReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 4e32e5b26..c81b95282 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -235,6 +235,11 @@ type GlanceSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Glance Service Template glancev1.GlanceSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` } // CinderSection defines the desired state of Cinder service diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 0c0d49b47..a0c52c9ad 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -106,6 +106,7 @@ func (in *GaleraSection) DeepCopy() *GaleraSection { func (in *GlanceSection) DeepCopyInto(out *GlanceSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlanceSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 0dc0abd34..3543548b7 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -2140,6 +2140,107 @@ spec: type: object glance: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index 68419222a..ab85acb0e 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -82,6 +82,24 @@ spec: path: glance.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool + displayName: IPAddress Pool + path: glance.externalEndpoints[0].ipAddressPool + - description: LoadBalancerIPs, request given IPs from the pool if available. + Using a list to allow dual stack (IPv4/IPv6) support + displayName: Load Balancer IPs + path: glance.externalEndpoints[0].loadBalancerIPs + - description: SharedIP if true, VIP/VIPs get shared with multiple services + displayName: Shared IP + path: glance.externalEndpoints[0].sharedIP + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: SharedIPKey specifies the sharing key which gets set as the annotation + on the LoadBalancer service. Services which share the same VIP must have + the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, + but no SharedIPKey specified. + displayName: Shared IPKey + path: glance.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating the Glance Service displayName: Template path: glance.template diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 52ec6ca86..7d5c1d203 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -57,16 +57,13 @@ spec: - storage replicas: 0 # backend needs to be configured glance: + apiOverride: + route: {} template: databaseInstance: openstack storageClass: "" storageRequest: 10G glanceAPIInternal: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: 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 f564e8981..a6c848474 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -57,16 +57,13 @@ spec: - storage replicas: 0 # backend needs to be configured glance: + apiOverride: + route: {} template: databaseInstance: openstack storageClass: "" storageRequest: 10G glanceAPIInternal: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 3c04363cf..4c9f767ad 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -57,16 +57,13 @@ spec: - storage replicas: 0 # backend needs to be configured glance: + apiOverride: + route: {} template: databaseInstance: openstack storageClass: "" storageRequest: 10G glanceAPIInternal: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index beffb0a10..b8bc96be6 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -92,6 +92,8 @@ spec: - storage replicas: 0 # backend needs to be configured glance: + apiOverride: + route: {} template: databaseInstance: openstack customServiceConfig: | @@ -107,11 +109,6 @@ spec: storageClass: "" storageRequest: 10G glanceAPIInternal: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: diff --git a/pkg/openstack/glance.go b/pkg/openstack/glance.go index 5decc025b..447235f64 100644 --- a/pkg/openstack/glance.go +++ b/pkg/openstack/glance.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" glancev1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/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,66 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneGlanceReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeGlanceReadyCondition) return ctrl.Result{}, nil } + serviceOverrides := map[service.Endpoint]service.RoutedOverrideSpec{} + if instance.Spec.Glance.Template.GlanceAPIExternal.Override.Service != nil { + serviceOverrides[service.EndpointPublic] = *instance.Spec.Glance.Template.GlanceAPIExternal.Override.Service + } + if instance.Spec.Glance.Template.GlanceAPIInternal.Override.Service != nil { + serviceOverrides[service.EndpointInternal] = *instance.Spec.Glance.Template.GlanceAPIInternal.Override.Service + } + + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + svcOverride := serviceOverrides[endpointType] + serviceOverrides[endpointType] = AddServiceComponentLabel(svcOverride, glance.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: "glance", Namespace: instance.Namespace}, glance); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + if glance.Status.Conditions.IsTrue(glancev1.GlanceAPIReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: glance.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + serviceOverrides, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + glance, + svcs, + serviceOverrides, + instance.Spec.Glance.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeGlanceReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling Glance", "Glance.Namespace", instance.Namespace, "Glance.Name", "glance") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), glance, func() error { instance.Spec.Glance.Template.DeepCopyInto(&glance.Spec) + glance.Spec.GlanceAPIExternal.Override.Service = ptr.To(serviceOverrides[service.EndpointPublic]) + glance.Spec.GlanceAPIInternal.Override.Service = ptr.To(serviceOverrides[service.EndpointInternal]) + if glance.Spec.Secret == "" { glance.Spec.Secret = instance.Spec.Secret } @@ -90,5 +150,4 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl } return ctrl.Result{}, nil - } From 7f771afba74121567af9c9b34b46d22ec5f1933c Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Fri, 4 Aug 2023 11:32:23 +0200 Subject: [PATCH 03/13] Create placementapi route and svc endpoint overrides Creates the route for the placementapi, 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/placement-operator/pull/48 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 ++++++++++++++++++ ...nstack-operator.clusterserviceversion.yaml | 18 ++++ ...controlplane_galera_network_isolation.yaml | 11 +- ...ne_galera_network_isolation_3replicas.yaml | 11 +- ...enstackcontrolplane_network_isolation.yaml | 11 +- ...ckcontrolplane_network_isolation_ceph.yaml | 11 +- pkg/openstack/placement.go | 53 +++++++++ 11 files changed, 298 insertions(+), 28 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 3543548b7..836db0a91 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -7600,6 +7600,107 @@ spec: type: object placement: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 7e60bf43d..c74cfbbb5 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -39,6 +39,9 @@ const ( // OpenStackControlPlanePlacementAPIReadyCondition Status=True condition which indicates if PlacementAPI is configured and operational OpenStackControlPlanePlacementAPIReadyCondition condition.Type = "OpenStackControlPlanePlacementAPIReady" + // OpenStackControlPlaneExposePlacementAPIReadyCondition Status=True condition which indicates if PlacementAPI is exposed via a route + OpenStackControlPlaneExposePlacementAPIReadyCondition condition.Type = "OpenStackControlPlaneExposePlacementAPIReady" + // OpenStackControlPlaneGlanceReadyCondition Status=True condition which indicates if Glance is configured and operational OpenStackControlPlaneGlanceReadyCondition condition.Type = "OpenStackControlPlaneGlanceReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index c81b95282..d34bb15df 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -221,6 +221,11 @@ type PlacementSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Placement API Template placementv1.PlacementAPISpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` } // GlanceSection defines the desired state of Glance service diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index a0c52c9ad..d1d34b202 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -543,6 +543,7 @@ func (in *OvnSection) DeepCopy() *OvnSection { func (in *PlacementSection) DeepCopyInto(out *PlacementSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 3543548b7..836db0a91 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -7600,6 +7600,107 @@ spec: type: object placement: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index ab85acb0e..9867387e0 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -249,6 +249,24 @@ spec: path: placement.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool + displayName: IPAddress Pool + path: placement.externalEndpoints[0].ipAddressPool + - description: LoadBalancerIPs, request given IPs from the pool if available. + Using a list to allow dual stack (IPv4/IPv6) support + displayName: Load Balancer IPs + path: placement.externalEndpoints[0].loadBalancerIPs + - description: SharedIP if true, VIP/VIPs get shared with multiple services + displayName: Shared IP + path: placement.externalEndpoints[0].sharedIP + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: SharedIPKey specifies the sharing key which gets set as the annotation + on the LoadBalancer service. Services which share the same VIP must have + the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, + but no SharedIPKey specified. + displayName: Shared IPKey + path: placement.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating the Placement API displayName: Template path: placement.template diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 7d5c1d203..2dad9dfee 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -223,14 +223,9 @@ spec: ovn-encap-type: "geneve" networkAttachment: tenant placement: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -241,6 +236,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret rabbitmq: templates: rabbitmq: 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 a6c848474..2923b690d 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -223,14 +223,9 @@ spec: ovn-encap-type: "geneve" networkAttachment: tenant placement: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -241,6 +236,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret rabbitmq: templates: rabbitmq: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 4c9f767ad..4aa21ace6 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -211,14 +211,9 @@ spec: ovn-encap-type: "geneve" networkAttachment: tenant placement: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -229,6 +224,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret rabbitmq: templates: rabbitmq: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index b8bc96be6..2d26cd3a8 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -269,14 +269,9 @@ spec: ovn-encap-type: "geneve" networkAttachment: tenant placement: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -287,6 +282,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret rabbitmq: templates: rabbitmq: diff --git a/pkg/openstack/placement.go b/pkg/openstack/placement.go index 398a052c1..388d5a1dd 100644 --- a/pkg/openstack/placement.go +++ b/pkg/openstack/placement.go @@ -4,14 +4,19 @@ 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" placementv1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,12 +34,60 @@ func ReconcilePlacementAPI(ctx context.Context, instance *corev1beta1.OpenStackC return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlanePlacementAPIReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposePlacementAPIReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Placement.Template.Override.Service == nil { + instance.Spec.Placement.Template.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Placement.Template.Override.Service[endpointType] = AddServiceComponentLabel( + instance.Spec.Placement.Template.Override.Service[endpointType], + placementAPI.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: "placement", Namespace: instance.Namespace}, placementAPI); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + if placementAPI.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: placementAPI.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Placement.Template.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + placementAPI, + svcs, + instance.Spec.Placement.Template.Override.Service, + instance.Spec.Placement.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposePlacementAPIReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling PlacementAPI", "PlacementAPI.Namespace", instance.Namespace, "PlacementAPI.Name", "placement") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), placementAPI, func() error { instance.Spec.Placement.Template.DeepCopyInto(&placementAPI.Spec) + if placementAPI.Spec.Secret == "" { placementAPI.Spec.Secret = instance.Spec.Secret } From 15e32ad1832f4e05a2a1c019121208d977594eab Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Fri, 4 Aug 2023 17:15:14 +0200 Subject: [PATCH 04/13] Create cinderapi route and svc endpoint overrides Creates the route for the cinderapi, 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/cinder-operator/pull/248 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 ++++++++++++++++++ ...nstack-operator.clusterserviceversion.yaml | 18 ++++ ...controlplane_galera_network_isolation.yaml | 7 +- ...ne_galera_network_isolation_3replicas.yaml | 7 +- ...enstackcontrolplane_network_isolation.yaml | 7 +- ...ckcontrolplane_network_isolation_ceph.yaml | 7 +- pkg/openstack/cinder.go | 54 ++++++++++ 11 files changed, 291 insertions(+), 20 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 836db0a91..e5cf1f0b9 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -99,6 +99,107 @@ spec: type: object cinder: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index c74cfbbb5..b2a5de511 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -51,6 +51,9 @@ const ( // OpenStackControlPlaneCinderReadyCondition Status=True condition which indicates if Cinder is configured and operational OpenStackControlPlaneCinderReadyCondition condition.Type = "OpenStackControlPlaneCinderReady" + // OpenStackControlPlaneExposeCinderReadyCondition Status=True condition which indicates if Cinder is exposed via a route + OpenStackControlPlaneExposeCinderReadyCondition condition.Type = "OpenStackControlPlaneExposeCinderReady" + // OpenStackControlPlaneOVNReadyCondition Status=True condition which indicates if OVN is configured and operational OpenStackControlPlaneOVNReadyCondition condition.Type = "OpenStackControlPlaneOVNReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index d34bb15df..e51675943 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -259,6 +259,11 @@ type CinderSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating Cinder Resources Template cinderv1.CinderSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` } // MariadbSection defines the desired state of MariaDB service diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index d1d34b202..be945048f 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -52,6 +52,7 @@ func (in *CeilometerSection) DeepCopy() *CeilometerSection { func (in *CinderSection) DeepCopyInto(out *CinderSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 836db0a91..e5cf1f0b9 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -99,6 +99,107 @@ spec: type: object cinder: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index 9867387e0..b1766e6c0 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -43,6 +43,24 @@ spec: path: cinder.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool + displayName: IPAddress Pool + path: cinder.externalEndpoints[0].ipAddressPool + - description: LoadBalancerIPs, request given IPs from the pool if available. + Using a list to allow dual stack (IPv4/IPv6) support + displayName: Load Balancer IPs + path: cinder.externalEndpoints[0].loadBalancerIPs + - description: SharedIP if true, VIP/VIPs get shared with multiple services + displayName: Shared IP + path: cinder.externalEndpoints[0].sharedIP + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: SharedIPKey specifies the sharing key which gets set as the annotation + on the LoadBalancer service. Services which share the same VIP must have + the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, + but no SharedIPKey specified. + displayName: Shared IPKey + path: cinder.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating Cinder Resources displayName: Template path: cinder.template diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 2dad9dfee..c319cbb63 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -26,15 +26,12 @@ spec: - 192.168.122.1 replicas: 1 cinder: + apiOverride: + route: {} template: databaseInstance: openstack secret: osp-secret cinderAPI: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: 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 2923b690d..0b6fe6a74 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -26,15 +26,12 @@ spec: - 192.168.122.1 replicas: 1 cinder: + apiOverride: + route: {} template: databaseInstance: openstack secret: osp-secret cinderAPI: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 4aa21ace6..ac74231cf 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -26,15 +26,12 @@ spec: - 192.168.122.1 replicas: 1 cinder: + apiOverride: + route: {} template: databaseInstance: openstack secret: osp-secret cinderAPI: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index 2d26cd3a8..bb03aafcf 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -46,15 +46,12 @@ spec: - 192.168.122.1 replicas: 1 cinder: + apiOverride: + route: {} template: databaseInstance: openstack secret: osp-secret cinderAPI: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: diff --git a/pkg/openstack/cinder.go b/pkg/openstack/cinder.go index 01f5daccc..a0be02e74 100644 --- a/pkg/openstack/cinder.go +++ b/pkg/openstack/cinder.go @@ -4,14 +4,19 @@ 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" cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,12 +34,61 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneCinderReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeCinderReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Cinder.Template.CinderAPI.Override.Service == nil { + instance.Spec.Cinder.Template.CinderAPI.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Cinder.Template.CinderAPI.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Cinder.Template.CinderAPI.Override.Service[endpointType], + cinder.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: "cinder", Namespace: instance.Namespace}, cinder); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + if cinder.Status.Conditions.IsTrue(cinderv1.CinderAPIReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: cinder.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Cinder.Template.CinderAPI.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + cinder, + svcs, + instance.Spec.Cinder.Template.CinderAPI.Override.Service, + instance.Spec.Cinder.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeCinderReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling Cinder", "Cinder.Namespace", instance.Namespace, "Cinder.Name", "cinder") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), cinder, func() error { instance.Spec.Cinder.Template.DeepCopyInto(&cinder.Spec) + if cinder.Spec.Secret == "" { cinder.Spec.Secret = instance.Spec.Secret } From 35a396d4701b5fa5e57080188aeb56041ba0abe5 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Mon, 7 Aug 2023 15:44:03 +0200 Subject: [PATCH 05/13] Create neutronapi route and svc endpoint overrides Creates the route for the neutronapi, 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/neutron-operator/pull/194 Jira: OSP-26690 --- ....openstack.org_openstackcontrolplanes.yaml | 101 ++++++++++++++++++ apis/core/v1beta1/conditions.go | 3 + .../v1beta1/openstackcontrolplane_types.go | 7 +- apis/core/v1beta1/zz_generated.deepcopy.go | 1 + ....openstack.org_openstackcontrolplanes.yaml | 101 ++++++++++++++++++ ...controlplane_galera_network_isolation.yaml | 11 +- ...ne_galera_network_isolation_3replicas.yaml | 11 +- ...enstackcontrolplane_network_isolation.yaml | 11 +- ...ckcontrolplane_network_isolation_ceph.yaml | 11 +- pkg/openstack/neutron.go | 54 ++++++++++ 10 files changed, 282 insertions(+), 29 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index e5cf1f0b9..06f54a0e8 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -5761,6 +5761,107 @@ spec: type: object neutron: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index b2a5de511..85575211e 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -60,6 +60,9 @@ const ( // OpenStackControlPlaneNeutronReadyCondition Status=True condition which indicates if Neutron is configured and operational OpenStackControlPlaneNeutronReadyCondition condition.Type = "OpenStackControlPlaneNeutronReady" + // OpenStackControlPlaneExposeNeutronReadyCondition Status=True condition which indicates if Neutron is exposed via a route + OpenStackControlPlaneExposeNeutronReadyCondition condition.Type = "OpenStackControlPlaneExposeNeutronReady" + // OpenStackControlPlaneNovaReadyCondition Status=True condition which indicates if Nova is configured and operational OpenStackControlPlaneNovaReadyCondition condition.Type = "OpenStackControlPlaneNovaReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index e51675943..37c6b25aa 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -411,8 +411,13 @@ type NeutronSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec - // Template - Overrides to use when creating the Neutron service + // Template - Overrides to use when creating the Neutron Service Template neutronv1.NeutronAPISpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` } // NovaSection defines the desired state of Nova services diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index be945048f..5707465a9 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -269,6 +269,7 @@ func (in *MetalLBConfig) DeepCopy() *MetalLBConfig { func (in *NeutronSection) DeepCopyInto(out *NeutronSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NeutronSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index e5cf1f0b9..06f54a0e8 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -5761,6 +5761,107 @@ spec: type: object neutron: properties: + apiOverride: + 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 enabled: default: true type: boolean diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index c319cbb63..4a23cd548 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -114,14 +114,9 @@ spec: memcached: replicas: 1 neutron: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -132,6 +127,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret networkAttachments: - internalapi horizon: 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 0b6fe6a74..df881fbc7 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -114,14 +114,9 @@ spec: memcached: replicas: 1 neutron: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -132,6 +127,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret networkAttachments: - internalapi horizon: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index ac74231cf..5103d9b2d 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -102,14 +102,9 @@ spec: memcached: replicas: 1 neutron: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -120,6 +115,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret networkAttachments: - internalapi horizon: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index bb03aafcf..93922d542 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -147,14 +147,9 @@ spec: memcached: replicas: 1 neutron: + apiOverride: + route: {} template: - databaseInstance: openstack - secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -165,6 +160,8 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + databaseInstance: openstack + secret: osp-secret networkAttachments: - internalapi horizon: diff --git a/pkg/openstack/neutron.go b/pkg/openstack/neutron.go index 6cb439642..7a15f0e26 100644 --- a/pkg/openstack/neutron.go +++ b/pkg/openstack/neutron.go @@ -4,14 +4,19 @@ 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" neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,12 +34,61 @@ func ReconcileNeutron(ctx context.Context, instance *corev1beta1.OpenStackContro return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneNeutronReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeNeutronReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Neutron.Template.Override.Service == nil { + instance.Spec.Neutron.Template.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Neutron.Template.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Neutron.Template.Override.Service[endpointType], + neutronAPI.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: "neutron", Namespace: instance.Namespace}, neutronAPI); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + if neutronAPI.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: neutronAPI.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Neutron.Template.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + neutronAPI, + svcs, + instance.Spec.Neutron.Template.Override.Service, + instance.Spec.Neutron.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeNeutronReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling NeutronAPI", "NeutronAPI.Namespace", instance.Namespace, "NeutronAPI.Name", "neutron") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), neutronAPI, func() error { instance.Spec.Neutron.Template.DeepCopyInto(&neutronAPI.Spec) + if neutronAPI.Spec.Secret == "" { neutronAPI.Spec.Secret = instance.Spec.Secret } From b31042668115e6ea53e7d04ac780641ccb383ad5 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Mon, 7 Aug 2023 18:16:57 +0200 Subject: [PATCH 06/13] Create nova route and svc endpoint overrides Creates the route for the nova components, 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/nova-operator/pull/489 Jira: OSP-26690 --- ....openstack.org_openstackcontrolplanes.yaml | 207 ++++++++++++++++++ apis/core/v1beta1/conditions.go | 3 + .../v1beta1/openstackcontrolplane_types.go | 18 ++ apis/core/v1beta1/zz_generated.deepcopy.go | 24 ++ ....openstack.org_openstackcontrolplanes.yaml | 207 ++++++++++++++++++ ...controlplane_galera_network_isolation.yaml | 14 +- ...ne_galera_network_isolation_3replicas.yaml | 14 +- ...enstackcontrolplane_network_isolation.yaml | 14 +- ...ckcontrolplane_network_isolation_ceph.yaml | 14 +- pkg/openstack/nova.go | 128 +++++++++++ 10 files changed, 599 insertions(+), 44 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 06f54a0e8..3c652089a 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -6780,6 +6780,213 @@ spec: type: object nova: properties: + apiOverride: + 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 + cellOverride: + additionalProperties: + properties: + noVNCProxy: + 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 + type: object + type: object enabled: default: true type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 85575211e..4c68e4d77 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -66,6 +66,9 @@ const ( // OpenStackControlPlaneNovaReadyCondition Status=True condition which indicates if Nova is configured and operational OpenStackControlPlaneNovaReadyCondition condition.Type = "OpenStackControlPlaneNovaReady" + // OpenStackControlPlaneExposeNovaReadyCondition Status=True condition which indicates if Nova is exposed via a route + OpenStackControlPlaneExposeNovaReadyCondition condition.Type = "OpenStackControlPlaneExposeNovaReady" + // OpenStackControlPlaneHeatReadyCondition Status=True condition which indicates if Heat is configured and operational OpenStackControlPlaneHeatReadyCondition condition.Type = "OpenStackControlPlaneHeatReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 37c6b25aa..c16bd5b73 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -432,6 +432,24 @@ type NovaSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Nova services Template novav1.NovaSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // CellOverride, provides the ability to override the generated manifest of several child resources + // for a nova cell. cell0 never have compute nodes and therefore it won't have a noVNCProxy deployed. + // Providing an override for cell0 noVNCProxy does not have an effect. + CellOverride map[string]NovaCellOverrideSpec `json:"cellOverride,omitempty"` +} + +// NovaCellOverrideSpec to override the generated manifest of several child resources. +type NovaCellOverrideSpec struct { + // +kubebuilder:validation:Optional + NoVNCProxy Override `json:"noVNCProxy,omitempty"` } // HeatSection defines the desired state of Heat services diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 5707465a9..4a5f1fcb4 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -282,10 +282,34 @@ func (in *NeutronSection) DeepCopy() *NeutronSection { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NovaCellOverrideSpec) DeepCopyInto(out *NovaCellOverrideSpec) { + *out = *in + in.NoVNCProxy.DeepCopyInto(&out.NoVNCProxy) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NovaCellOverrideSpec. +func (in *NovaCellOverrideSpec) DeepCopy() *NovaCellOverrideSpec { + if in == nil { + return nil + } + out := new(NovaCellOverrideSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NovaSection) DeepCopyInto(out *NovaSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.CellOverride != nil { + in, out := &in.CellOverride, &out.CellOverride + *out = make(map[string]NovaCellOverrideSpec, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NovaSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 06f54a0e8..3c652089a 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -6780,6 +6780,213 @@ spec: type: object nova: properties: + apiOverride: + 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 + cellOverride: + additionalProperties: + properties: + noVNCProxy: + 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 + type: object + type: object enabled: default: true type: boolean diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 4a23cd548..bf7e982b9 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -136,13 +136,10 @@ spec: replicas: 1 secret: osp-secret nova: + apiOverride: + route: {} template: apiServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -153,13 +150,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - secret: osp-secret metadataServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: @@ -169,6 +160,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + secret: osp-secret manila: template: manilaAPI: 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 df881fbc7..1ff0a3a7b 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -136,13 +136,10 @@ spec: replicas: 1 secret: osp-secret nova: + apiOverride: + route: {} template: apiServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -153,13 +150,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - secret: osp-secret metadataServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: @@ -169,6 +160,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + secret: osp-secret manila: template: manilaAPI: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 5103d9b2d..f371493c6 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -124,13 +124,10 @@ spec: replicas: 1 secret: osp-secret nova: + apiOverride: + route: {} template: apiServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -141,13 +138,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - secret: osp-secret metadataServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: @@ -157,6 +148,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + secret: osp-secret manila: template: manilaAPI: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index 93922d542..05b23d144 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -169,13 +169,10 @@ spec: replicas: 1 secret: osp-secret nova: + apiOverride: + route: {} template: apiServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: internal: @@ -186,13 +183,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - secret: osp-secret metadataServiceTemplate: - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 override: service: metadata: @@ -202,6 +193,7 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer + secret: osp-secret manila: template: manilaAPI: diff --git a/pkg/openstack/nova.go b/pkg/openstack/nova.go index 6ff791b9d..13e13b14e 100644 --- a/pkg/openstack/nova.go +++ b/pkg/openstack/nova.go @@ -20,14 +20,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" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/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" ) @@ -45,9 +51,127 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneNovaReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeNovaReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + // NovaAPI + if instance.Spec.Nova.Template.APIServiceTemplate.Override.Service == nil { + instance.Spec.Nova.Template.APIServiceTemplate.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Nova.Template.APIServiceTemplate.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Nova.Template.APIServiceTemplate.Override.Service[endpointType], + nova.Name+"-api") + + // cell NoVNCProxy service override + for cellName, cellTemplate := range instance.Spec.Nova.Template.CellTemplates { + // skip adding override for all the cells where novncproxy is disabled + if cellTemplate.NoVNCProxyServiceTemplate.Enabled == ptr.To(false) { + continue + } + if cellTemplate.NoVNCProxyServiceTemplate.Override.Service == nil { + cellTemplate.NoVNCProxyServiceTemplate.Override.Service = &service.RoutedOverrideSpec{} + } + + *cellTemplate.NoVNCProxyServiceTemplate.Override.Service = + AddServiceComponentLabel( + *cellTemplate.NoVNCProxyServiceTemplate.Override.Service, + getNoVNCProxyServiceLabel(nova.Name, cellName)) + + instance.Spec.Nova.Template.CellTemplates[cellName] = cellTemplate + } + } + + // When component services got created check if there is the need to create a route + if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "nova", Namespace: instance.Namespace}, nova); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + // Nova API + if nova.Status.Conditions.IsTrue(novav1.NovaAPIReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: nova.Name + "-api"}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Nova.Template.APIServiceTemplate.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + nova, + svcs, + instance.Spec.Nova.Template.APIServiceTemplate.Override.Service, + instance.Spec.Nova.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeNovaReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + + if nova.Status.Conditions.IsTrue(novav1.NovaAllCellsReadyCondition) { + // cell NoVNCProxy + for cellName, cellTemplate := range instance.Spec.Nova.Template.CellTemplates { + // skip checking for/creating route if service is not enabled + if cellTemplate.NoVNCProxyServiceTemplate.Enabled == ptr.To(false) { + continue + } + + if cellTemplate.NoVNCProxyServiceTemplate.Override.Service == nil { + cellTemplate.NoVNCProxyServiceTemplate.Override.Service = &service.RoutedOverrideSpec{} + } + + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{ + common.AppSelector: getNoVNCProxyServiceLabel(nova.Name, cellName), + }, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + routedOverrideSpec, ctrlResult, err := EnsureRoute( + ctx, + instance, + helper, + nova, + svcs, + map[service.Endpoint]service.RoutedOverrideSpec{ + service.EndpointInternal: *cellTemplate.NoVNCProxyServiceTemplate.Override.Service, + }, + instance.Spec.Nova.CellOverride[cellName].NoVNCProxy.Route, + corev1beta1.OpenStackControlPlaneExposeNovaReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + cellTemplate.NoVNCProxyServiceTemplate.Override.Service = ptr.To(routedOverrideSpec[service.EndpointInternal]) + + instance.Spec.Nova.Template.CellTemplates[cellName] = cellTemplate + + } + } + helper.GetLogger().Info("Reconciling Nova", "Nova.Namespace", instance.Namespace, "Nova.Name", nova.Name) op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), nova, func() error { // 1) @@ -100,3 +224,7 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl return ctrl.Result{}, nil } + +func getNoVNCProxyServiceLabel(name string, cellName string) string { + return name + "-novncproxy-" + cellName +} From 0c554ea3fd4a1b9e69ba778578518406703a2567 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Fri, 11 Aug 2023 09:48:58 +0200 Subject: [PATCH 07/13] Create heatapi and heatcfnapi route and svc endpoint overrides Creates the route for the heatapi and heatcfnapi, 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/heat-operator/pull/227 Jira: OSP-26690 --- ....openstack.org_openstackcontrolplanes.yaml | 202 ++++++++++++++++++ apis/core/v1beta1/conditions.go | 3 + .../v1beta1/openstackcontrolplane_types.go | 10 + apis/core/v1beta1/zz_generated.deepcopy.go | 2 + ....openstack.org_openstackcontrolplanes.yaml | 202 ++++++++++++++++++ ...controlplane_galera_network_isolation.yaml | 24 +++ ...ne_galera_network_isolation_3replicas.yaml | 24 +++ ...enstackcontrolplane_network_isolation.yaml | 24 +++ ...ckcontrolplane_network_isolation_ceph.yaml | 24 +++ pkg/openstack/heat.go | 94 ++++++++ 10 files changed, 609 insertions(+) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 3c652089a..5700592a7 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -3423,6 +3423,208 @@ spec: type: object heat: properties: + apiOverride: + 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 + cnfAPIOverride: + 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 enabled: default: false type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 4c68e4d77..512a4f82c 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -72,6 +72,9 @@ const ( // OpenStackControlPlaneHeatReadyCondition Status=True condition which indicates if Heat is configured and operational OpenStackControlPlaneHeatReadyCondition condition.Type = "OpenStackControlPlaneHeatReady" + // OpenStackControlPlaneExposeHeatReadyCondition Status=True condition which indicates if Heat is exposed via a route + OpenStackControlPlaneExposeHeatReadyCondition condition.Type = "OpenStackControlPlaneExposeHeatReady" + // OpenStackControlPlaneIronicReadyCondition Status=True condition which indicates if Ironic is configured and operational OpenStackControlPlaneIronicReadyCondition condition.Type = "OpenStackControlPlaneIronicReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index c16bd5b73..0aa4fae6c 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -464,6 +464,16 @@ type HeatSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Heat services Template heatv1.HeatSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // CnfAPIOverride, provides the ability to override the generated manifest of several child resources. + CnfAPIOverride Override `json:"cnfAPIOverride,omitempty"` } // IronicSection defines the desired state of Ironic services diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 4a5f1fcb4..de9d2a2d3 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -124,6 +124,8 @@ func (in *GlanceSection) DeepCopy() *GlanceSection { func (in *HeatSection) DeepCopyInto(out *HeatSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) + in.CnfAPIOverride.DeepCopyInto(&out.CnfAPIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeatSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 3c652089a..5700592a7 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -3423,6 +3423,208 @@ spec: type: object heat: properties: + apiOverride: + 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 + cnfAPIOverride: + 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 enabled: default: false type: boolean diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index bf7e982b9..960af247a 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -239,12 +239,36 @@ spec: ipAddressPool: internalapi sharedIP: false heat: + apiOverride: + route: {} + cnfAPIOverride: + route: {} enabled: false template: databaseInstance: openstack heatAPI: + 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 replicas: 1 heatEngine: + 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 replicas: 1 secret: osp-secret ironic: 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 1ff0a3a7b..028c2dc31 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -239,12 +239,36 @@ spec: ipAddressPool: internalapi sharedIP: false heat: + apiOverride: + route: {} + cnfAPIOverride: + route: {} enabled: false template: databaseInstance: openstack heatAPI: + 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 replicas: 1 heatEngine: + 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 replicas: 1 secret: osp-secret ironic: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index f371493c6..6c7d5d5bd 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -227,12 +227,36 @@ spec: ipAddressPool: internalapi sharedIP: false heat: + apiOverride: + route: {} + cnfAPIOverride: + route: {} enabled: false template: databaseInstance: openstack heatAPI: + 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 replicas: 1 heatEngine: + 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 replicas: 1 secret: osp-secret ironic: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index 05b23d144..8f8ac8258 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -285,12 +285,36 @@ spec: ipAddressPool: internalapi sharedIP: false heat: + apiOverride: + route: {} + cnfAPIOverride: + route: {} enabled: false template: databaseInstance: openstack heatAPI: + 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 replicas: 1 heatEngine: + 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 replicas: 1 secret: osp-secret ironic: diff --git a/pkg/openstack/heat.go b/pkg/openstack/heat.go index ff3ef8ade..033699b2d 100644 --- a/pkg/openstack/heat.go +++ b/pkg/openstack/heat.go @@ -4,14 +4,19 @@ 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" heatv1 "github.com/openstack-k8s-operators/heat-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,11 +34,100 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneHeatReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeHeatReadyCondition) return ctrl.Result{}, nil } + + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Heat.Template.HeatAPI.Override.Service == nil { + instance.Spec.Heat.Template.HeatAPI.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Heat.Template.HeatAPI.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Heat.Template.HeatAPI.Override.Service[endpointType], + heat.Name+"-api") + + if instance.Spec.Heat.Template.HeatCfnAPI.Override.Service == nil { + instance.Spec.Heat.Template.HeatCfnAPI.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Heat.Template.HeatCfnAPI.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Heat.Template.HeatCfnAPI.Override.Service[endpointType], + heat.Name+"-cfn") + } + + // When component services got created check if there is the need to create a route + if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "heat", Namespace: instance.Namespace}, heat); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + // Heat API + if heat.Status.Conditions.IsTrue(heatv1.HeatAPIReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: heat.Name + "-api"}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Heat.Template.HeatAPI.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + heat, + svcs, + instance.Spec.Heat.Template.HeatAPI.Override.Service, + instance.Spec.Heat.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeHeatReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + + // Heat CFNAPI + if heat.Status.Conditions.IsTrue(heatv1.HeatCfnAPIReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: heat.Name + "-cfn"}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Heat.Template.HeatCfnAPI.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + heat, + svcs, + instance.Spec.Heat.Template.HeatCfnAPI.Override.Service, + instance.Spec.Heat.CnfAPIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeHeatReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconcile heat", "heat.Namespace", instance.Namespace, "heat.Name", "heat") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), heat, func() error { instance.Spec.Heat.Template.DeepCopyInto(&heat.Spec) + err := controllerutil.SetControllerReference(helper.GetBeforeObject(), heat, helper.GetScheme()) if err != nil { return err From e9220acf0f34258d672b4417743a7cf59652238d Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Fri, 11 Aug 2023 12:00:49 +0200 Subject: [PATCH 08/13] Create horizon route and svc overrides Creates the route for the horizon, 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/horizon-operator/pull/202 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 | 2 + ...ne_galera_network_isolation_3replicas.yaml | 2 + ...enstackcontrolplane_network_isolation.yaml | 2 + ...ckcontrolplane_network_isolation_ceph.yaml | 2 + pkg/openstack/horizon.go | 67 ++++++++++++ 10 files changed, 286 insertions(+) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 5700592a7..4e039ec9d 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -3975,6 +3975,107 @@ spec: type: object horizon: properties: + apiOverride: + 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 enabled: default: false type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 512a4f82c..d7795448c 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -81,6 +81,9 @@ const ( // OpenStackControlPlaneHorizonReadyCondition Status=True condition which indicates if Horizon is configured and operational OpenStackControlPlaneHorizonReadyCondition condition.Type = "OpenStackControlPlaneHorizonReady" + // OpenStackControlPlaneExposeHorizonReadyCondition Status=True condition which indicates if Horizon is exposed via a route + OpenStackControlPlaneExposeHorizonReadyCondition condition.Type = "OpenStackControlPlaneExposeHorizonReady" + // OpenStackControlPlaneClientReadyCondition Status=True condition which indicates if OpenStackClient is configured and operational OpenStackControlPlaneClientReadyCondition condition.Type = "OpenStackControlPlaneClientReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 0aa4fae6c..e0c283886 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -513,6 +513,11 @@ type HorizonSection struct { // +kubebuilder:validation:Optional // Template - Overrides to use when creating the Horizon services Template horizonv1.HorizonSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` } // CeilometerSection defines the desired state of OpenStack Telemetry services diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index de9d2a2d3..4053695ff 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -142,6 +142,7 @@ func (in *HeatSection) DeepCopy() *HeatSection { func (in *HorizonSection) DeepCopyInto(out *HorizonSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizonSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 5700592a7..4e039ec9d 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -3975,6 +3975,107 @@ spec: type: object horizon: properties: + apiOverride: + 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 enabled: default: false type: boolean diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 960af247a..f4c201145 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -132,6 +132,8 @@ spec: networkAttachments: - internalapi horizon: + apiOverride: + route: {} template: replicas: 1 secret: osp-secret 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 028c2dc31..4044e72d6 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -132,6 +132,8 @@ spec: networkAttachments: - internalapi horizon: + apiOverride: + route: {} template: replicas: 1 secret: osp-secret diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 6c7d5d5bd..ac8888c3e 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -120,6 +120,8 @@ spec: networkAttachments: - internalapi horizon: + apiOverride: + route: {} template: replicas: 1 secret: osp-secret diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index 8f8ac8258..e5f29faa0 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -165,6 +165,8 @@ spec: networkAttachments: - internalapi horizon: + apiOverride: + route: {} template: replicas: 1 secret: osp-secret diff --git a/pkg/openstack/horizon.go b/pkg/openstack/horizon.go index 84f7a6ed8..ce61ed5d7 100644 --- a/pkg/openstack/horizon.go +++ b/pkg/openstack/horizon.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" horizonv1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/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,11 +35,72 @@ func ReconcileHorizon(ctx context.Context, instance *corev1beta1.OpenStackContro return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneHorizonReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeHorizonReadyCondition) return ctrl.Result{}, nil } + + // add selector to service overrides + /* + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Horizon.Template.Override.Service == nil { + instance.Spec.Horizon.Template.Override.Service = map[string]service.RoutedOverrideSpec{} + } + instance.Spec.Horizon.Template.Override.Service[string(endpointType)] = + AddServiceComponentLabel( + ptr.To(instance.Spec.Horizon.Template.Override.Service[string(endpointType)]), + horizon.Name) + */ + serviceOverrides := map[service.Endpoint]service.RoutedOverrideSpec{} + if instance.Spec.Horizon.Template.Override.Service != nil { + serviceOverrides[service.EndpointPublic] = *instance.Spec.Horizon.Template.Override.Service + } + + // add selector to service overrides + serviceOverrides[service.EndpointPublic] = AddServiceComponentLabel( + serviceOverrides[service.EndpointPublic], + horizon.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: "horizon", Namespace: instance.Namespace}, horizon); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + if horizon.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: horizon.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + serviceOverrides, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + horizon, + svcs, + serviceOverrides, + instance.Spec.Horizon.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeHorizonReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconcile Horizon", "horizon.Namespace", instance.Namespace, "horizon.Name", "horizon") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), horizon, func() error { instance.Spec.Horizon.Template.DeepCopyInto(&horizon.Spec) + horizon.Spec.Override.Service = ptr.To(serviceOverrides[service.EndpointPublic]) + err := controllerutil.SetControllerReference(helper.GetBeforeObject(), horizon, helper.GetScheme()) if err != nil { return err From 41476498ca609a2e432950bd283982da717126c6 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Mon, 14 Aug 2023 10:04:54 +0200 Subject: [PATCH 09/13] Create manilaapi route and svc overrides Creates the route for the manila, 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/manila-operator/pull/117 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 | 11 +- ...ne_galera_network_isolation_3replicas.yaml | 11 +- ...enstackcontrolplane_network_isolation.yaml | 11 +- ...ckcontrolplane_network_isolation_ceph.yaml | 11 +- pkg/openstack/manila.go | 46 ++++++++ 10 files changed, 273 insertions(+), 28 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 4e039ec9d..f174cd5aa 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -4942,6 +4942,107 @@ spec: type: object manila: properties: + apiOverride: + 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 enabled: default: false type: boolean diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index d7795448c..b20482f15 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -93,6 +93,9 @@ const ( // OpenStackControlPlaneManilaReadyCondition Status=True condition which indicates if Manila is configured and operational OpenStackControlPlaneManilaReadyCondition condition.Type = "OpenStackControlPlaneManilaReady" + // OpenStackControlPlaneExposeManilaReadyCondition Status=True condition which indicates if Manila is exposed via a route + OpenStackControlPlaneExposeManilaReadyCondition condition.Type = "OpenStackControlPlaneExposeManilaReady" + // OpenStackControlPlaneDNSReadyCondition Status=True condition which indicates if DNSMasq is configured and operational OpenStackControlPlaneDNSReadyCondition condition.Type = "OpenStackControlPlaneDNSReadyCondition" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index e0c283886..ad057032c 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -501,6 +501,11 @@ type ManilaSection struct { // +kubebuilder:validation:Optional // Template - Overrides to use when creating Manila Resources Template manilav1.ManilaSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` } // HorizonSection defines the desired state of Horizon services diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 4053695ff..2db37e6e8 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -192,6 +192,7 @@ func (in *KeystoneSection) DeepCopy() *KeystoneSection { func (in *ManilaSection) DeepCopyInto(out *ManilaSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManilaSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 4e039ec9d..f174cd5aa 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -4942,6 +4942,107 @@ spec: type: object manila: properties: + apiOverride: + 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 enabled: default: false type: boolean diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index f4c201145..947898245 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -164,14 +164,13 @@ spec: type: LoadBalancer secret: osp-secret manila: + apiOverride: + route: {} template: manilaAPI: replicas: 1 - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 + networkAttachments: + - internalapi override: service: internal: @@ -182,8 +181,6 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - networkAttachments: - - internalapi manilaScheduler: replicas: 1 manilaShares: 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 4044e72d6..f0ebf5bab 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -164,14 +164,13 @@ spec: type: LoadBalancer secret: osp-secret manila: + apiOverride: + route: {} template: manilaAPI: replicas: 1 - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 + networkAttachments: + - internalapi override: service: internal: @@ -182,8 +181,6 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - networkAttachments: - - internalapi manilaScheduler: replicas: 1 manilaShares: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index ac8888c3e..b472a4dc6 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -152,14 +152,13 @@ spec: type: LoadBalancer secret: osp-secret manila: + apiOverride: + route: {} template: manilaAPI: replicas: 1 - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 + networkAttachments: + - internalapi override: service: internal: @@ -170,8 +169,6 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - networkAttachments: - - internalapi manilaScheduler: replicas: 1 manilaShares: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index e5f29faa0..ba7e2a52e 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -197,14 +197,13 @@ spec: type: LoadBalancer secret: osp-secret manila: + apiOverride: + route: {} template: manilaAPI: replicas: 1 - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 + networkAttachments: + - internalapi override: service: internal: @@ -215,8 +214,6 @@ spec: metallb.universe.tf/loadBalancerIPs: 172.17.0.80 spec: type: LoadBalancer - networkAttachments: - - internalapi manilaScheduler: replicas: 1 manilaShares: diff --git a/pkg/openstack/manila.go b/pkg/openstack/manila.go index a32cd7b8f..35088b782 100644 --- a/pkg/openstack/manila.go +++ b/pkg/openstack/manila.go @@ -4,10 +4,13 @@ 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" manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" @@ -29,12 +32,55 @@ func ReconcileManila(ctx context.Context, instance *corev1beta1.OpenStackControl return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneManilaReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeManilaReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Manila.Template.ManilaAPI.Override.Service == nil { + instance.Spec.Manila.Template.ManilaAPI.Override.Service = map[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Manila.Template.ManilaAPI.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Manila.Template.ManilaAPI.Override.Service[endpointType], + manila.Name) + } + + // When component services got created check if there is the need to create a route + if manila.Status.Conditions.IsTrue(manilav1.ManilaAPIReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: manila.Name}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Manila.Template.ManilaAPI.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + manila, + svcs, + instance.Spec.Manila.Template.ManilaAPI.Override.Service, + instance.Spec.Manila.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeManilaReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling Manila", "Manila.Namespace", instance.Namespace, "Manila.Name", "manila") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), manila, func() error { instance.Spec.Manila.Template.DeepCopyInto(&manila.Spec) + if manila.Spec.Secret == "" { manila.Spec.Secret = instance.Spec.Secret } From 38dd2772c05228ed30c5830d56cab2d35ca254b3 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Mon, 14 Aug 2023 11:50:44 +0200 Subject: [PATCH 10/13] 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 | 54 ++++++++++ 9 files changed, 301 insertions(+) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index f174cd5aa..26b31134b 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -12739,6 +12739,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 b20482f15..d4b66a104 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 ad057032c..64fd4e35b 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -551,6 +551,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 2db37e6e8..8aa91e5b9 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -655,6 +655,7 @@ func (in *RedisSection) DeepCopy() *RedisSection { 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 f174cd5aa..26b31134b 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -12739,6 +12739,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 947898245..65f6779f3 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -292,6 +292,8 @@ spec: serviceUser: ceilometer swift: enabled: true + proxyOverride: + route: {} template: swiftRing: ringReplicas: 1 @@ -299,6 +301,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 f0ebf5bab..d4a4521de 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -292,6 +292,8 @@ spec: serviceUser: ceilometer swift: enabled: true + proxyOverride: + route: {} template: swiftRing: ringReplicas: 1 @@ -299,6 +301,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 b472a4dc6..44dbfc30a 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -280,6 +280,8 @@ spec: serviceUser: ceilometer swift: enabled: true + proxyOverride: + route: {} template: swiftRing: ringReplicas: 1 @@ -287,6 +289,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..006c3a50c 100644 --- a/pkg/openstack/swift.go +++ b/pkg/openstack/swift.go @@ -4,14 +4,19 @@ 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" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,12 +34,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[service.Endpoint]service.RoutedOverrideSpec{} + } + instance.Spec.Swift.Template.SwiftProxy.Override.Service[endpointType] = + AddServiceComponentLabel( + instance.Spec.Swift.Template.SwiftProxy.Override.Service[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 From 377725cc397b56de1aaf6a0a93c24c7692832a27 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Thu, 17 Aug 2023 09:42:29 +0200 Subject: [PATCH 11/13] Remove MetalLB endpoint type and use instead override for rabbitmq --- ....openstack.org_openstackcontrolplanes.yaml | 24 ----------- .../v1beta1/openstackcontrolplane_types.go | 40 ------------------- apis/core/v1beta1/zz_generated.deepcopy.go | 25 ------------ ....openstack.org_openstackcontrolplanes.yaml | 24 ----------- ...controlplane_galera_network_isolation.yaml | 26 +++++++----- ...ne_galera_network_isolation_3replicas.yaml | 26 +++++++----- ...enstackcontrolplane_network_isolation.yaml | 26 +++++++----- ...ckcontrolplane_network_isolation_ceph.yaml | 26 +++++++----- pkg/openstack/rabbitmq.go | 36 +++-------------- 9 files changed, 70 insertions(+), 183 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 26b31134b..d148c7da3 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -9036,30 +9036,6 @@ spec: type: array type: object type: object - externalEndpoint: - properties: - endpoint: - default: internal - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object image: type: string imagePullSecrets: diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 64fd4e35b..90fe302ea 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -28,7 +28,6 @@ import ( keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/route" - "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/util" "github.com/openstack-k8s-operators/lib-common/modules/storage" manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" @@ -328,45 +327,6 @@ type RabbitmqTemplate struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Overrides to use when creating the Rabbitmq clusters rabbitmqv1.RabbitmqClusterSpec `json:",inline"` - - // +kubebuilder:validation:Optional - //+operator-sdk:csv:customresourcedefinitions:type=spec - // ExternalEndpoint, expose a VIP via MetalLB on the pre-created address pool - ExternalEndpoint *MetalLBConfig `json:"externalEndpoint,omitempty"` -} - -// MetalLBConfig to configure the MetalLB loadbalancer service -type MetalLBConfig struct { - // +kubebuilder:validation:Optional - // +kubebuilder:validation:Enum=internal;public - // +kubebuilder:default=internal - // Endpoint, OpenStack endpoint this service maps to - Endpoint service.Endpoint `json:"endpoint"` - - // +kubebuilder:validation:Required - // +kubebuilder:validation:MinLength=1 - //+operator-sdk:csv:customresourcedefinitions:type=spec - // IPAddressPool expose VIP via MetalLB on the IPAddressPool - IPAddressPool string `json:"ipAddressPool"` - - // +kubebuilder:validation:Optional - // +kubebuilder:default=true - // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} - // SharedIP if true, VIP/VIPs get shared with multiple services - SharedIP bool `json:"sharedIP"` - - // +kubebuilder:validation:Optional - // +kubebuilder:default="" - //+operator-sdk:csv:customresourcedefinitions:type=spec - // SharedIPKey specifies the sharing key which gets set as the annotation on the LoadBalancer service. - // Services which share the same VIP must have the same SharedIPKey. Defaults to the IPAddressPool if - // SharedIP is true, but no SharedIPKey specified. - SharedIPKey string `json:"sharedIPKey"` - - // +kubebuilder:validation:Optional - //+operator-sdk:csv:customresourcedefinitions:type=spec - // LoadBalancerIPs, request given IPs from the pool if available. Using a list to allow dual stack (IPv4/IPv6) support - LoadBalancerIPs []string `json:"loadBalancerIPs"` } // OvnSection defines the desired state of OVN services diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 8aa91e5b9..377d38bf8 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -249,26 +249,6 @@ func (in *MemcachedSection) DeepCopy() *MemcachedSection { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetalLBConfig) DeepCopyInto(out *MetalLBConfig) { - *out = *in - if in.LoadBalancerIPs != nil { - in, out := &in.LoadBalancerIPs, &out.LoadBalancerIPs - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetalLBConfig. -func (in *MetalLBConfig) DeepCopy() *MetalLBConfig { - if in == nil { - return nil - } - out := new(MetalLBConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NeutronSection) DeepCopyInto(out *NeutronSection) { *out = *in @@ -612,11 +592,6 @@ func (in *RabbitmqSection) DeepCopy() *RabbitmqSection { func (in *RabbitmqTemplate) DeepCopyInto(out *RabbitmqTemplate) { *out = *in in.RabbitmqClusterSpec.DeepCopyInto(&out.RabbitmqClusterSpec) - if in.ExternalEndpoint != nil { - in, out := &in.ExternalEndpoint, &out.ExternalEndpoint - *out = new(MetalLBConfig) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RabbitmqTemplate. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 26b31134b..d148c7da3 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -9036,30 +9036,6 @@ spec: type: array type: object type: object - externalEndpoint: - properties: - endpoint: - default: internal - enum: - - internal - - public - type: string - ipAddressPool: - minLength: 1 - type: string - loadBalancerIPs: - items: - type: string - type: array - sharedIP: - default: true - type: boolean - sharedIPKey: - default: "" - type: string - required: - - ipAddressPool - type: object image: type: string imagePullSecrets: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 65f6779f3..e92de3fb3 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -226,17 +226,23 @@ spec: rabbitmq: templates: rabbitmq: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.85 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.85 + spec: + type: LoadBalancer rabbitmq-cell1: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.86 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.86 + spec: + type: LoadBalancer heat: apiOverride: route: {} 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 d4a4521de..a3e12eec3 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -226,17 +226,23 @@ spec: rabbitmq: templates: rabbitmq: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.85 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.85 + spec: + type: LoadBalancer rabbitmq-cell1: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.86 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.86 + spec: + type: LoadBalancer heat: apiOverride: route: {} diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 44dbfc30a..2273ac4d0 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -214,17 +214,23 @@ spec: rabbitmq: templates: rabbitmq: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.85 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.85 + spec: + type: LoadBalancer rabbitmq-cell1: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.86 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.86 + spec: + type: LoadBalancer heat: apiOverride: route: {} diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index ba7e2a52e..31d254c12 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -272,17 +272,23 @@ spec: rabbitmq: templates: rabbitmq: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.85 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.85 + spec: + type: LoadBalancer rabbitmq-cell1: - externalEndpoint: - loadBalancerIPs: - - 172.17.0.86 - ipAddressPool: internalapi - sharedIP: false + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.86 + spec: + type: LoadBalancer heat: apiOverride: route: {} diff --git a/pkg/openstack/rabbitmq.go b/pkg/openstack/rabbitmq.go index b7f7a0295..89172404c 100644 --- a/pkg/openstack/rabbitmq.go +++ b/pkg/openstack/rabbitmq.go @@ -8,7 +8,7 @@ import ( networkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" condition "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" + "github.com/openstack-k8s-operators/lib-common/modules/common/util" rabbitmqv1 "github.com/rabbitmq/cluster-operator/api/v1beta1" // Cannot use the following import due to linting error: @@ -186,35 +186,11 @@ func reconcileRabbitMQ( rabbitmq.Spec.Override.StatefulSet = &defaultStatefulSet } - if rabbitmq.Spec.Override.Service == nil && spec.ExternalEndpoint != nil { - helper.GetLogger().Info("Setting MetalLB Service") - - metalLBSvcAnnotations := map[string]string{ - service.MetalLBAddressPoolAnnotation: spec.ExternalEndpoint.IPAddressPool, - networkv1.AnnotationHostnameKey: fmt.Sprintf("%s.%s.svc", name, instance.Namespace), - } - if len(spec.ExternalEndpoint.LoadBalancerIPs) > 0 { - metalLBSvcAnnotations[service.MetalLBLoadBalancerIPs] = strings.Join(spec.ExternalEndpoint.LoadBalancerIPs, ",") - } - if spec.ExternalEndpoint.SharedIP { - if spec.ExternalEndpoint.SharedIPKey == "" { - metalLBSvcAnnotations[service.MetalLBAllowSharedIPAnnotation] = spec.ExternalEndpoint.IPAddressPool - } else { - metalLBSvcAnnotations[service.MetalLBAllowSharedIPAnnotation] = spec.ExternalEndpoint.SharedIPKey - } - } - - //service.MetalLBService{} - metalLBSvc := rabbitmqv1.Service{ - EmbeddedLabelsAnnotations: &rabbitmqv1.EmbeddedLabelsAnnotations{ - Annotations: metalLBSvcAnnotations, - }, - Spec: &corev1.ServiceSpec{ - Type: corev1.ServiceTypeLoadBalancer, - }, - } - - rabbitmq.Spec.Override.Service = &metalLBSvc + if rabbitmq.Spec.Override.Service != nil && + rabbitmq.Spec.Override.Service.Spec.Type == corev1.ServiceTypeLoadBalancer { + rabbitmq.Spec.Override.Service.Annotations = + util.MergeStringMaps(rabbitmq.Spec.Override.Service.Annotations, + map[string]string{networkv1.AnnotationHostnameKey: fmt.Sprintf("%s.%s.svc", name, instance.Namespace)}) } if rabbitmq.Spec.Rabbitmq.AdditionalConfig == "" { From 36becc792c031ebc40df905e7356f46201b786be Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Mon, 11 Sep 2023 14:00:30 +0200 Subject: [PATCH 12/13] Update DNSMasq to use serviceOverride instead of externalEndpoints --- ...1beta1_openstackcontrolplane_galera_network_isolation.yaml | 4 ---- ...nstackcontrolplane_galera_network_isolation_3replicas.yaml | 4 ---- .../core_v1beta1_openstackcontrolplane_network_isolation.yaml | 4 ---- ..._v1beta1_openstackcontrolplane_network_isolation_ceph.yaml | 4 ---- 4 files changed, 16 deletions(-) diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index e92de3fb3..4e1901f91 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -7,10 +7,6 @@ spec: storageClass: local-storage dns: template: - externalEndpoints: - - ipAddressPool: ctlplane - loadBalancerIPs: - - 192.168.122.80 override: service: metadata: 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 a3e12eec3..83f844e5b 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -7,10 +7,6 @@ spec: storageClass: local-storage dns: template: - externalEndpoints: - - ipAddressPool: ctlplane - loadBalancerIPs: - - 192.168.122.80 override: service: metadata: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 2273ac4d0..0619f35d2 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -7,10 +7,6 @@ spec: storageClass: local-storage dns: template: - externalEndpoints: - - ipAddressPool: ctlplane - loadBalancerIPs: - - 192.168.122.80 override: service: metadata: diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index 31d254c12..9703b564f 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -27,10 +27,6 @@ spec: readOnly: true dns: template: - externalEndpoints: - - ipAddressPool: ctlplane - loadBalancerIPs: - - 192.168.122.80 override: service: metadata: From a1e296f292ad21ca4bfd9782fe9a1d8dad758498 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Thu, 21 Sep 2023 10:55:45 +0200 Subject: [PATCH 13/13] update kuttl tests for route create --- .../common/assert-sample-deployment.yaml | 28 +++++++++++++ .../common/errors_cleanup_openstack.yaml | 40 +++++++++++++++++++ .../collapsed/01-assert-collapsed-cell.yaml | 24 +++++++++++ .../01-assert-galera-3replicas.yaml | 24 +++++++++++ .../tests/galera-basic/01-assert-galera.yaml | 28 +++++++++++++ 5 files changed, 144 insertions(+) diff --git a/tests/kuttl/common/assert-sample-deployment.yaml b/tests/kuttl/common/assert-sample-deployment.yaml index 3412a3eed..9e1b69611 100644 --- a/tests/kuttl/common/assert-sample-deployment.yaml +++ b/tests/kuttl/common/assert-sample-deployment.yaml @@ -157,6 +157,34 @@ status: reason: Ready status: "True" type: OpenStackControlPlaneClientReady + - message: OpenStackControlPlane cinder service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeCinderReady + - message: OpenStackControlPlane glance service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeGlanceReady + - message: OpenStackControlPlane keystone service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeKeystoneAPIReady + - message: OpenStackControlPlane neutron service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNeutronReady + - message: OpenStackControlPlane nova service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNovaReady + - message: OpenStackControlPlane placement service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposePlacementAPIReady + - message: OpenStackControlPlane swift service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeSwiftReady - message: OpenStackControlPlane Glance completed reason: Ready status: "True" diff --git a/tests/kuttl/common/errors_cleanup_openstack.yaml b/tests/kuttl/common/errors_cleanup_openstack.yaml index d44ed9965..1e95b4b0d 100644 --- a/tests/kuttl/common/errors_cleanup_openstack.yaml +++ b/tests/kuttl/common/errors_cleanup_openstack.yaml @@ -182,3 +182,43 @@ metadata: openshift.io/scc: anyuid labels: service: neutron +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: cinder-public +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: glance-public +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: keystone-public +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: neutron-public +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: nova-public +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: nova-novncproxy-cell1-public +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: placement-public +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: swift-public diff --git a/tests/kuttl/tests/collapsed/01-assert-collapsed-cell.yaml b/tests/kuttl/tests/collapsed/01-assert-collapsed-cell.yaml index 723b6bbe4..2038be6c9 100644 --- a/tests/kuttl/tests/collapsed/01-assert-collapsed-cell.yaml +++ b/tests/kuttl/tests/collapsed/01-assert-collapsed-cell.yaml @@ -122,6 +122,30 @@ status: reason: Ready status: "True" type: OpenStackControlPlaneClientReady + - message: OpenStackControlPlane cinder service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeCinderReady + - message: OpenStackControlPlane glance service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeGlanceReady + - message: OpenStackControlPlane keystone service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeKeystoneAPIReady + - message: OpenStackControlPlane neutron service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNeutronReady + - message: OpenStackControlPlane nova service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNovaReady + - message: OpenStackControlPlane placement service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposePlacementAPIReady - message: OpenStackControlPlane Glance completed reason: Ready status: "True" diff --git a/tests/kuttl/tests/galera-3replicas/01-assert-galera-3replicas.yaml b/tests/kuttl/tests/galera-3replicas/01-assert-galera-3replicas.yaml index f72b12c42..11d0de2ed 100644 --- a/tests/kuttl/tests/galera-3replicas/01-assert-galera-3replicas.yaml +++ b/tests/kuttl/tests/galera-3replicas/01-assert-galera-3replicas.yaml @@ -132,6 +132,30 @@ status: reason: Ready status: "True" type: OpenStackControlPlaneClientReady + - message: OpenStackControlPlane cinder service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeCinderReady + - message: OpenStackControlPlane glance service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeGlanceReady + - message: OpenStackControlPlane keystone service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeKeystoneAPIReady + - message: OpenStackControlPlane neutron service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNeutronReady + - message: OpenStackControlPlane nova service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNovaReady + - message: OpenStackControlPlane placement service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposePlacementAPIReady - message: OpenStackControlPlane Glance completed reason: Ready status: "True" diff --git a/tests/kuttl/tests/galera-basic/01-assert-galera.yaml b/tests/kuttl/tests/galera-basic/01-assert-galera.yaml index 6691c0bce..ccd7a9cc0 100644 --- a/tests/kuttl/tests/galera-basic/01-assert-galera.yaml +++ b/tests/kuttl/tests/galera-basic/01-assert-galera.yaml @@ -151,6 +151,34 @@ status: reason: Ready status: "True" type: OpenStackControlPlaneClientReady + - message: OpenStackControlPlane cinder service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeCinderReady + - message: OpenStackControlPlane glance service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeGlanceReady + - message: OpenStackControlPlane keystone service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeKeystoneAPIReady + - message: OpenStackControlPlane neutron service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNeutronReady + - message: OpenStackControlPlane nova service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeNovaReady + - message: OpenStackControlPlane placement service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposePlacementAPIReady + - message: OpenStackControlPlane swift service exposed + reason: Ready + status: "True" + type: OpenStackControlPlaneExposeSwiftReady - message: OpenStackControlPlane Glance completed reason: Ready status: "True"