From 3e034088655002457fde585ea07687a649f99d88 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Thu, 27 Jul 2023 12:01:36 +0200 Subject: [PATCH] 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 | 1875 +++++++++++++---- apis/core/v1beta1/conditions.go | 12 + .../v1beta1/openstackcontrolplane_types.go | 29 +- .../v1beta1/openstackcontrolplane_webhook.go | 2 +- apis/core/v1beta1/zz_generated.deepcopy.go | 29 + apis/go.mod | 20 + apis/go.sum | 28 +- ....openstack.org_openstackcontrolplanes.yaml | 1875 +++++++++++++---- ...nstack-operator.clusterserviceversion.yaml | 18 + config/rbac/role.yaml | 12 + ...controlplane_galera_network_isolation.yaml | 10 +- ...ne_galera_network_isolation_3replicas.yaml | 10 +- ...enstackcontrolplane_network_isolation.yaml | 10 +- ...ckcontrolplane_network_isolation_ceph.yaml | 10 +- .../core/openstackcontrolplane_controller.go | 3 + go.mod | 24 +- go.sum | 28 +- main.go | 2 + pkg/openstack/common.go | 291 +++ pkg/openstack/keystone.go | 67 + 20 files changed, 3470 insertions(+), 885 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 92c852ec8..ac6d56ba9 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -126,32 +126,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 @@ -160,6 +134,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -2894,32 +2985,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 @@ -2928,6 +2993,121 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: object pvc: type: string replicas: @@ -2990,32 +3170,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 @@ -3024,50 +3178,165 @@ spec: additionalProperties: type: string type: object - pvc: - type: string - replicas: - default: 1 - format: int32 - maximum: 32 - minimum: 0 - type: integer - resources: + override: properties: - claims: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - required: - - containerImage - type: object - nodeSelector: - additionalProperties: + service: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: object + pvc: + type: string + replicas: + default: 1 + format: int32 + maximum: 32 + minimum: 0 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + required: + - containerImage + type: object + nodeSelector: + additionalProperties: type: string type: object passwordSelectors: @@ -3926,6 +4195,133 @@ spec: type: object keystone: properties: + apiOverride: + properties: + externalEndpoints: + items: + 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 + type: array + 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 @@ -3962,32 +4358,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 @@ -3999,49 +4369,166 @@ spec: additionalProperties: type: string type: object - passwordSelectors: - default: - admin: AdminPassword - database: KeystoneDatabasePassword - properties: - admin: - default: AdminPassword - type: string - database: - default: KeystoneDatabasePassword - type: string - type: object - preserveJobs: - default: false - type: boolean - region: - default: regionOne - type: string - replicas: - default: 1 - format: int32 - maximum: 32 - minimum: 0 - type: integer - resources: + override: properties: - claims: + service: items: properties: - name: + endpoint: + enum: + - internal + - public type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object + passwordSelectors: + default: + admin: AdminPassword + database: KeystoneDatabasePassword + properties: + admin: + default: AdminPassword + type: string + database: + default: KeystoneDatabasePassword + type: string + type: object + preserveJobs: + default: false + type: boolean + region: + default: regionOne + type: string + replicas: + default: 1 + format: int32 + maximum: 32 + minimum: 0 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object @@ -5209,32 +5696,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: @@ -5999,89 +6460,206 @@ spec: additionalProperties: type: string type: object - passwordSelectors: - default: - database: NeutronDatabasePassword - service: NeutronPassword + override: properties: - database: - default: NeutronDatabasePassword - type: string service: - default: NeutronPassword - type: string - type: object - preserveJobs: - default: false - type: boolean - rabbitMqClusterName: - default: rabbitmq - type: string - replicas: - default: 1 - format: int32 - maximum: 32 - minimum: 0 - type: integer - resources: - properties: - claims: items: properties: - name: + endpoint: + enum: + - internal + - public type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - secret: - type: string - serviceUser: - default: neutron - type: string - required: - - containerImage - - databaseInstance - - rabbitMqClusterName - - secret - type: object - type: object - nodeSelector: - additionalProperties: - type: string - type: object - nova: - properties: - enabled: - default: true - type: boolean - template: - properties: - apiDatabaseInstance: - default: openstack - type: string - apiDatabaseUser: - default: nova_api + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object + passwordSelectors: + default: + database: NeutronDatabasePassword + service: NeutronPassword + properties: + database: + default: NeutronDatabasePassword + type: string + service: + default: NeutronPassword + type: string + type: object + preserveJobs: + default: false + type: boolean + rabbitMqClusterName: + default: rabbitmq + type: string + replicas: + default: 1 + format: int32 + maximum: 32 + minimum: 0 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + secret: + type: string + serviceUser: + default: neutron + type: string + required: + - containerImage + - databaseInstance + - rabbitMqClusterName + - secret + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + nova: + properties: + enabled: + default: true + type: boolean + template: + properties: + apiDatabaseInstance: + default: openstack + type: string + apiDatabaseUser: + default: nova_api type: string apiMessageBusInstance: default: rabbitmq @@ -6098,31 +6676,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 @@ -6131,6 +6684,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -6252,31 +6922,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 @@ -6285,6 +6930,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -6333,31 +7095,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 @@ -6366,6 +7103,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -6457,31 +7311,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 @@ -6490,6 +7319,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -7023,32 +7969,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 @@ -7057,6 +7977,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object passwordSelectors: default: database: PlacementDatabasePassword @@ -7495,6 +8532,12 @@ spec: type: object externalEndpoint: properties: + endpoint: + default: internal + enum: + - internal + - public + type: string ipAddressPool: minLength: 1 type: string diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 5d44a3b08..5bb56f144 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -75,6 +75,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" @@ -321,4 +324,13 @@ const ( // OpenStackControlPlaneCeilometerReadyErrorMessage OpenStackControlPlaneCeilometerReadyErrorMessage = "OpenStackControlPlane Ceilometer error occured %s" + + // OpenStackControlPlaneServiceOverrideReadyInitMessage + OpenStackControlPlaneServiceOverrideReadyInitMessage = "OpenStackControlPlane service override not started" + + // OpenStackControlPlaneServiceOverrideReadyMessage + OpenStackControlPlaneServiceOverrideReadyMessage = "OpenStackControlPlane service overrides completed" + + // OpenStackControlPlaneServiceOverrideReadyErrorMessage + OpenStackControlPlaneServiceOverrideReadyErrorMessage = "OpenStackControlPlane %s service endpoint %s override error occured %s" ) diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index ea4408dd2..4e416414d 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -28,18 +28,20 @@ import ( 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" - octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -188,9 +190,24 @@ 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"` + + // ExternalEndpoints, expose a VIP using a pre-created IPAddressPool + ExternalEndpoints []MetalLBConfig `json:"externalEndpoints,omitempty"` } // PlacementSection defines the desired state of Placement service @@ -306,6 +323,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 @@ -556,6 +579,8 @@ func (instance *OpenStackControlPlane) InitConditions() { instance.Status.Conditions = condition.Conditions{} } cl := condition.CreateList( + condition.UnknownCondition(OpenStackControlPlaneServiceOverrideReadyCondition, condition.InitReason, OpenStackControlPlaneServiceOverrideReadyInitMessage), + condition.UnknownCondition(condition.ExposeServiceReadyCondition, condition.InitReason, condition.ExposeServiceReadyInitMessage), condition.UnknownCondition(OpenStackControlPlaneRabbitMQReadyCondition, condition.InitReason, OpenStackControlPlaneRabbitMQReadyInitMessage), condition.UnknownCondition(OpenStackControlPlaneOVNReadyCondition, condition.InitReason, OpenStackControlPlaneOVNReadyInitMessage), condition.UnknownCondition(OpenStackControlPlaneNeutronReadyCondition, condition.InitReason, OpenStackControlPlaneNeutronReadyInitMessage), diff --git a/apis/core/v1beta1/openstackcontrolplane_webhook.go b/apis/core/v1beta1/openstackcontrolplane_webhook.go index 971bc5807..0fcb94c4b 100644 --- a/apis/core/v1beta1/openstackcontrolplane_webhook.go +++ b/apis/core/v1beta1/openstackcontrolplane_webhook.go @@ -158,7 +158,7 @@ func (r *OpenStackControlPlane) checkDepsEnabled(name string) string { case "Octavia": if !((r.Spec.Mariadb.Enabled || r.Spec.Galera.Enabled) && r.Spec.Memcached.Enabled && r.Spec.Rabbitmq.Enabled && r.Spec.Keystone.Enabled && r.Spec.Neutron.Enabled && r.Spec.Glance.Enabled && r.Spec.Nova.Enabled && - r.Spec.Ovn.Enabled) { + r.Spec.Ovn.Enabled) { reqs = "MariaDB or Galera, Memcached, RabbitMQ, Keystone, Glance, Neutron, Nova, OVN" } } diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 3654c91a0..d4bd75acd 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -24,6 +24,7 @@ package v1beta1 import ( memcachedv1beta1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/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" @@ -168,6 +169,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. @@ -474,6 +476,33 @@ 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) + } + if in.ExternalEndpoints != nil { + in, out := &in.ExternalEndpoints, &out.ExternalEndpoints + *out = make([]MetalLBConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// 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 2b271d411..8074b9ea3 100644 --- a/apis/go.mod +++ b/apis/go.mod @@ -100,3 +100,23 @@ require ( // mschuppert: map to latest commit from release-4.13 tag // must consistent within modules and service operators replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 + +//replace github.com/openstack-k8s-operators/lib-common/modules/common => /home/mschuppe/src/github.com/openstack-k8s-operators/lib-common/modules/common + +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4 + +//replace github.com/openstack-k8s-operators/keystone-operator/api => /home/mschuppe/src/github.com/openstack-k8s-operators/keystone-operator/api + +//replace github.com/openstack-k8s-operators/glance-operator/api => /home/mschuppe/src/github.com/openstack-k8s-operators/glance-operator/api + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/stuggi/glance-operator/api v0.0.0-20230808075207-6b14ed16b49b + +replace github.com/openstack-k8s-operators/placement-operator/api => github.com/stuggi/placement-operator/api v0.0.0-20230808075127-11794bf73d00 + +replace github.com/openstack-k8s-operators/cinder-operator/api => github.com/stuggi/cinder-operator/api v0.0.0-20230808075052-d7ecd3000e0a + +replace github.com/openstack-k8s-operators/neutron-operator/api => github.com/stuggi/neutron-operator/api v0.0.0-20230807133748-6ed1a0824e3a + +replace github.com/openstack-k8s-operators/nova-operator/api => github.com/stuggi/nova-operator/api v0.0.0-20230808075321-5f810c0dcaa0 diff --git a/apis/go.sum b/apis/go.sum index 013d55b40..e9aaefb96 100644 --- a/apis/go.sum +++ b/apis/go.sum @@ -126,10 +126,6 @@ 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.0 h1:8QsJidoozdGsV9fSFzzgCstxMvi8tKtsY67+G/gWKB0= -github.com/openstack-k8s-operators/cinder-operator/api v0.1.0/go.mod h1:GEZ6VarA74XXRa4SagCymoRrxQQVWvxZ2K7O4/YSxK4= -github.com/openstack-k8s-operators/glance-operator/api v0.1.0 h1:FWYUz5iHzzh6b74eor+3t9h4GQojmLFXD4YzFApEWz4= -github.com/openstack-k8s-operators/glance-operator/api v0.1.0/go.mod h1:I7JjTjU7qvmVr5rqMvlDbhxa3pA3DlCH4ZENGNew6gg= github.com/openstack-k8s-operators/heat-operator/api v0.1.0 h1:OTYRtRUP3zwm0zg6JG/s2FYU7QT7xQNTFhMcMKpVRVU= github.com/openstack-k8s-operators/heat-operator/api v0.1.0/go.mod h1:xLPJun/7wSz9vgaoxn6wz9AZsYOVj1LnYexGMgHRAcc= github.com/openstack-k8s-operators/horizon-operator/api v0.1.0 h1:pwMfL2bZu8/pQ2QWzDT5thdeSvY6fI6P0iJkFeiT7a0= @@ -138,10 +134,6 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230807091437-b github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230807091437-ba548589f8e8/go.mod h1:t1xmsiZDqM3wXcLMqgHp7/iilK8ozuOkydV4Vi2Qibk= github.com/openstack-k8s-operators/ironic-operator/api v0.1.0 h1:Bm0mo2iRT16CG/WNj3stuheDGQDDZY3CGVv52AFDH1w= github.com/openstack-k8s-operators/ironic-operator/api v0.1.0/go.mod h1:slFWxIEbjO2tkyPR6GoKI0pIDgctKsPVB+Wg6D+CbQ0= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.0 h1:p98vKnS4KzdgU/+vrVKFY3y9n9v1Z6cpo4JvbTNRxlM= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.0/go.mod h1:LNJJdteQG4E2fhWDerE+f8S2/ephEJg8yBkH1eqYYOo= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0 h1:F1iYRBwa0cZ2VHw8Zs4frqSWQ1B/tiCuSwH/DuHb8VM= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0/go.mod h1:3hAC5Ce0AOSt85BqD6DgTKNkJHmpXwqbwL8mVWRJQqo= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0 h1:mMeJvCQfZmakssvMyHjzp/ngxKysETDj9GJYhRwydzg= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0/go.mod h1:+paEFOL5IlJzhg9fy7/1+HSErVkWUgUj1ORLFwgvxnI= github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.0 h1:rHn0wlwBBggRl65gWDniF97XW+1XB2+4PsGZS2RIJ5E= @@ -150,16 +142,10 @@ github.com/openstack-k8s-operators/manila-operator/api v0.1.0 h1:79TSB3A5+TLpK56 github.com/openstack-k8s-operators/manila-operator/api v0.1.0/go.mod h1:ywLIfMlreyF+19UNZw3ud84/Tlr4WffuopEUSXFTick= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.0 h1:oM0ZzFHHj+ioCc7NXHIO6+sy7I2yiN29DI9/jh4fe54= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.0/go.mod h1:m5XuZSa5Zt5uAw3WbJYOIkFAGXy01mybVekcKOq1qHI= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.0 h1:tGlQ4RPeFtgEHOnyqTnTzjzBaPHdpm0ieMMmQHl3XTg= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.0/go.mod h1:5VaQboKxg4t65Xt1xcddjjODrUHkwQo9LCUWiGqbFao= -github.com/openstack-k8s-operators/nova-operator/api v0.1.1 h1:4FHCnUBopafOdnR+JEHyPROdi5wUjOk7G9YcfP3rfIE= -github.com/openstack-k8s-operators/nova-operator/api v0.1.1/go.mod h1:bQWyn3wTGEjbWk6qzyL7IhcIl9xU5WcGBcKBZZiD3Uo= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230801112207-bcd92ba349f6 h1:/shGXE4n0F99yX8eDPVzZwDL/lnM5Z/HhUhvBwxnWI8= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230801112207-bcd92ba349f6/go.mod h1:SUnvwqdpvGNWSWe11yuu2M5Ns9FG0ge16tfNzwXmz/s= github.com/openstack-k8s-operators/ovn-operator/api v0.1.0 h1:AnmXOjUJMgxg8cRewjUIHfOCH1o3jTftYfvXiRGBjmA= github.com/openstack-k8s-operators/ovn-operator/api v0.1.0/go.mod h1:SSNSWIHTf2i/yM2KprT7FZeCuQfGwEf5eHnISi3zMAg= -github.com/openstack-k8s-operators/placement-operator/api v0.1.0 h1:i2UEgkyAommKa3Q3KOwQirbbiLW6EocS457S+3fc46s= -github.com/openstack-k8s-operators/placement-operator/api v0.1.0/go.mod h1:HTgKM7NBqtBKsCQaBbtF9xqNAjLAmaCGoFlCDmIu9I0= github.com/openstack-k8s-operators/swift-operator/api v0.1.0 h1:4d6o+qFzkm9vmIBiizjnL2D6QCqOIv8YTFVbWK7Dg20= github.com/openstack-k8s-operators/swift-operator/api v0.1.0/go.mod h1:7Ysj6252KjltNccUosTKbtBhw9NZ+Sys2esq0bKm18M= github.com/openstack-k8s-operators/telemetry-operator/api v0.1.0 h1:HF3SeZ3x6pbZrLxCmRkF+rIbaV8lISpA3gd2NCqX8D4= @@ -197,6 +183,20 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stuggi/cinder-operator/api v0.0.0-20230808075052-d7ecd3000e0a h1:Evy/ItVvgR94Wwlo7o7f2V3DbluJD4AIyFYUGyPNjso= +github.com/stuggi/cinder-operator/api v0.0.0-20230808075052-d7ecd3000e0a/go.mod h1:NiERYYJ4YYbxg2Ry5HyH+UI8pbvKap5GoZtW6Exk1pQ= +github.com/stuggi/glance-operator/api v0.0.0-20230808075207-6b14ed16b49b h1:YRBQHekvk9NHhbNOmNbR0OJZO48RizCfaQ6VyP960y4= +github.com/stuggi/glance-operator/api v0.0.0-20230808075207-6b14ed16b49b/go.mod h1:LD5Y1/RQInUqzluF7RtzPLuOeQjgfq7ek9ecPSkVvWw= +github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4 h1:qVwSTi3ZDWl8ITLcVBOwJlEDlMi3UyFykZh5qN76BSI= +github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4/go.mod h1:XdvO78DPVkkGFf5kPLDDb7a8/DGuv/JwxzhmipalUhw= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 h1:E5EGKIZHyAV1oofcXkcUq4NZfTtgFjjKpU6A0Yv2vls= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= +github.com/stuggi/neutron-operator/api v0.0.0-20230807133748-6ed1a0824e3a h1:cWcjdBMFPUg8+JOVVPY+WhKolV/McZIkHscqzDozkvM= +github.com/stuggi/neutron-operator/api v0.0.0-20230807133748-6ed1a0824e3a/go.mod h1:1RwvmP2LrLj/OJvSEl7hu3aYekB1EI79D1p/rfDxDZU= +github.com/stuggi/nova-operator/api v0.0.0-20230808075321-5f810c0dcaa0 h1:7zZX5Pu6Vlc2TLJs4arZK9wndIkeVUzFXjkeNIH8QL0= +github.com/stuggi/nova-operator/api v0.0.0-20230808075321-5f810c0dcaa0/go.mod h1:3Iin2b6jhn6ofsnUhl+WL3KQmC+QpDuimacCZZSUFIw= +github.com/stuggi/placement-operator/api v0.0.0-20230808075127-11794bf73d00 h1:UN2rIEvde98erkUPSUL/5j5KoshueEZZziVvG3d2RVo= +github.com/stuggi/placement-operator/api v0.0.0-20230808075127-11794bf73d00/go.mod h1:tg7n4eZXA5atHBLkUqSvD6EK3omwVN7fa5CSLZNBkFs= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 92c852ec8..ac6d56ba9 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -126,32 +126,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 @@ -160,6 +134,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -2894,32 +2985,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 @@ -2928,6 +2993,121 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: object pvc: type: string replicas: @@ -2990,32 +3170,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 @@ -3024,50 +3178,165 @@ spec: additionalProperties: type: string type: object - pvc: - type: string - replicas: - default: 1 - format: int32 - maximum: 32 - minimum: 0 - type: integer - resources: + override: properties: - claims: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - required: - - containerImage - type: object - nodeSelector: - additionalProperties: + service: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: object + pvc: + type: string + replicas: + default: 1 + format: int32 + maximum: 32 + minimum: 0 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + required: + - containerImage + type: object + nodeSelector: + additionalProperties: type: string type: object passwordSelectors: @@ -3926,6 +4195,133 @@ spec: type: object keystone: properties: + apiOverride: + properties: + externalEndpoints: + items: + 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 + type: array + 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 @@ -3962,32 +4358,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 @@ -3999,49 +4369,166 @@ spec: additionalProperties: type: string type: object - passwordSelectors: - default: - admin: AdminPassword - database: KeystoneDatabasePassword - properties: - admin: - default: AdminPassword - type: string - database: - default: KeystoneDatabasePassword - type: string - type: object - preserveJobs: - default: false - type: boolean - region: - default: regionOne - type: string - replicas: - default: 1 - format: int32 - maximum: 32 - minimum: 0 - type: integer - resources: + override: properties: - claims: + service: items: properties: - name: + endpoint: + enum: + - internal + - public type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object + passwordSelectors: + default: + admin: AdminPassword + database: KeystoneDatabasePassword + properties: + admin: + default: AdminPassword + type: string + database: + default: KeystoneDatabasePassword + type: string + type: object + preserveJobs: + default: false + type: boolean + region: + default: regionOne + type: string + replicas: + default: 1 + format: int32 + maximum: 32 + minimum: 0 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object @@ -5209,32 +5696,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: @@ -5999,89 +6460,206 @@ spec: additionalProperties: type: string type: object - passwordSelectors: - default: - database: NeutronDatabasePassword - service: NeutronPassword + override: properties: - database: - default: NeutronDatabasePassword - type: string service: - default: NeutronPassword - type: string - type: object - preserveJobs: - default: false - type: boolean - rabbitMqClusterName: - default: rabbitmq - type: string - replicas: - default: 1 - format: int32 - maximum: 32 - minimum: 0 - type: integer - resources: - properties: - claims: items: properties: - name: + endpoint: + enum: + - internal + - public type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - secret: - type: string - serviceUser: - default: neutron - type: string - required: - - containerImage - - databaseInstance - - rabbitMqClusterName - - secret - type: object - type: object - nodeSelector: - additionalProperties: - type: string - type: object - nova: - properties: - enabled: - default: true - type: boolean - template: - properties: - apiDatabaseInstance: - default: openstack - type: string - apiDatabaseUser: - default: nova_api + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object + passwordSelectors: + default: + database: NeutronDatabasePassword + service: NeutronPassword + properties: + database: + default: NeutronDatabasePassword + type: string + service: + default: NeutronPassword + type: string + type: object + preserveJobs: + default: false + type: boolean + rabbitMqClusterName: + default: rabbitmq + type: string + replicas: + default: 1 + format: int32 + maximum: 32 + minimum: 0 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + secret: + type: string + serviceUser: + default: neutron + type: string + required: + - containerImage + - databaseInstance + - rabbitMqClusterName + - secret + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + nova: + properties: + enabled: + default: true + type: boolean + template: + properties: + apiDatabaseInstance: + default: openstack + type: string + apiDatabaseUser: + default: nova_api type: string apiMessageBusInstance: default: rabbitmq @@ -6098,31 +6676,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 @@ -6131,6 +6684,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -6252,31 +6922,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 @@ -6285,6 +6930,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -6333,31 +7095,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 @@ -6366,6 +7103,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -6457,31 +7311,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 @@ -6490,6 +7319,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object replicas: default: 1 format: int32 @@ -7023,32 +7969,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 @@ -7057,6 +7977,123 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + items: + properties: + endpoint: + enum: + - internal + - public + type: string + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + required: + - endpoint + type: object + type: array + type: object passwordSelectors: default: database: PlacementDatabasePassword @@ -7495,6 +8532,12 @@ spec: type: object externalEndpoint: properties: + endpoint: + default: internal + enum: + - internal + - public + type: string ipAddressPool: minLength: 1 type: string diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index affbaed82..06e7017b4 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -117,6 +117,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 cc92d9754..154d0a12e 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -343,6 +343,18 @@ rules: - list - update - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - 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 5a50e645f..ea4f849d0 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -54,14 +54,14 @@ spec: networkAttachments: - storage keystone: + externalEndpoints: + - endpoint: internal + ipAddressPool: internalapi + loadBalancerIPs: + - 172.17.0.80 template: databaseInstance: openstack secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 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 8930a5287..b27eec345 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -54,14 +54,14 @@ spec: networkAttachments: - storage keystone: + externalEndpoints: + - endpoint: internal + ipAddressPool: internalapi + loadBalancerIPs: + - 172.17.0.80 template: databaseInstance: openstack secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 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 d0c962132..16c5e57d1 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -54,14 +54,14 @@ spec: networkAttachments: - storage keystone: + externalEndpoints: + - endpoint: internal + ipAddressPool: internalapi + loadBalancerIPs: + - 172.17.0.80 template: databaseInstance: openstack secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 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 ee119b8aa..ec6d465f2 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -98,14 +98,14 @@ spec: networkAttachments: - storage keystone: + externalEndpoints: + - endpoint: internal + ipAddressPool: internalapi + loadBalancerIPs: + - 172.17.0.80 template: databaseInstance: openstack secret: osp-secret - externalEndpoints: - - endpoint: internal - ipAddressPool: internalapi - loadBalancerIPs: - - 172.17.0.80 mariadb: templates: openstack: diff --git a/controllers/core/openstackcontrolplane_controller.go b/controllers/core/openstackcontrolplane_controller.go index 7845aa83c..bd4268893 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" @@ -85,6 +86,7 @@ type OpenStackControlPlaneReconciler struct { //+kubebuilder:rbac:groups=telemetry.openstack.org,resources=ceilometercentrals,verbs=get;list;watch;create;update;patch;delete //+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=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete; // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -323,5 +325,6 @@ func (r *OpenStackControlPlaneReconciler) SetupWithManager(mgr ctrl.Manager) err Owns(&horizonv1.Horizon{}). Owns(&telemetryv1.CeilometerCentral{}). Owns(&octaviav1.Octavia{}). + Owns(&routev1.Route{}). Complete(r) } diff --git a/go.mod b/go.mod index 6759d9f48..f8f3f50c6 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ 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/openshift/api v3.9.0+incompatible github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0 //indirect github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.0 //indirect github.com/pkg/errors v0.9.1 // indirect @@ -101,7 +101,7 @@ require ( k8s.io/component-base v0.26.7 //indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230515203736-54b630e78af5 //indirect - k8s.io/utils v0.0.0-20230711102312-30195339c3c7 //indirect + k8s.io/utils v0.0.0-20230711102312-30195339c3c7 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd //indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect @@ -112,3 +112,23 @@ replace github.com/openstack-k8s-operators/openstack-operator/apis => ./apis // mschuppert: map to latest commit from release-4.13 tag // must consistent within modules and service operators replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 + +//replace github.com/openstack-k8s-operators/lib-common/modules/common => /home/mschuppe/src/github.com/openstack-k8s-operators/lib-common/modules/common + +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4 + +//replace github.com/openstack-k8s-operators/keystone-operator/api => /home/mschuppe/src/github.com/openstack-k8s-operators/keystone-operator/api + +//replace github.com/openstack-k8s-operators/glance-operator/api => /home/mschuppe/src/github.com/openstack-k8s-operators/glance-operator/api + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/stuggi/glance-operator/api v0.0.0-20230808075207-6b14ed16b49b + +replace github.com/openstack-k8s-operators/placement-operator/api => github.com/stuggi/placement-operator/api v0.0.0-20230808075127-11794bf73d00 + +replace github.com/openstack-k8s-operators/cinder-operator/api => github.com/stuggi/cinder-operator/api v0.0.0-20230808075052-d7ecd3000e0a + +replace github.com/openstack-k8s-operators/neutron-operator/api => github.com/stuggi/neutron-operator/api v0.0.0-20230807133748-6ed1a0824e3a + +replace github.com/openstack-k8s-operators/nova-operator/api => github.com/stuggi/nova-operator/api v0.0.0-20230808075321-5f810c0dcaa0 diff --git a/go.sum b/go.sum index ba3b634ac..a542285d3 100644 --- a/go.sum +++ b/go.sum @@ -133,12 +133,8 @@ 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.0 h1:8QsJidoozdGsV9fSFzzgCstxMvi8tKtsY67+G/gWKB0= -github.com/openstack-k8s-operators/cinder-operator/api v0.1.0/go.mod h1:GEZ6VarA74XXRa4SagCymoRrxQQVWvxZ2K7O4/YSxK4= github.com/openstack-k8s-operators/dataplane-operator/api v0.1.1-0.20230807191505-cb7dc383f871 h1:xLsbkoDTWqJcYVh+4KiKhZv293cg5gLyJ/Rm7dAD3CQ= github.com/openstack-k8s-operators/dataplane-operator/api v0.1.1-0.20230807191505-cb7dc383f871/go.mod h1:p70g6k0BVBo+9BGt2ky9ZlG8f5s3ZOv7XQrNmiZ6S04= -github.com/openstack-k8s-operators/glance-operator/api v0.1.0 h1:FWYUz5iHzzh6b74eor+3t9h4GQojmLFXD4YzFApEWz4= -github.com/openstack-k8s-operators/glance-operator/api v0.1.0/go.mod h1:I7JjTjU7qvmVr5rqMvlDbhxa3pA3DlCH4ZENGNew6gg= github.com/openstack-k8s-operators/heat-operator/api v0.1.0 h1:OTYRtRUP3zwm0zg6JG/s2FYU7QT7xQNTFhMcMKpVRVU= github.com/openstack-k8s-operators/heat-operator/api v0.1.0/go.mod h1:xLPJun/7wSz9vgaoxn6wz9AZsYOVj1LnYexGMgHRAcc= github.com/openstack-k8s-operators/horizon-operator/api v0.1.0 h1:pwMfL2bZu8/pQ2QWzDT5thdeSvY6fI6P0iJkFeiT7a0= @@ -147,10 +143,6 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230807091437-b github.com/openstack-k8s-operators/infra-operator/apis v0.1.1-0.20230807091437-ba548589f8e8/go.mod h1:t1xmsiZDqM3wXcLMqgHp7/iilK8ozuOkydV4Vi2Qibk= github.com/openstack-k8s-operators/ironic-operator/api v0.1.0 h1:Bm0mo2iRT16CG/WNj3stuheDGQDDZY3CGVv52AFDH1w= github.com/openstack-k8s-operators/ironic-operator/api v0.1.0/go.mod h1:slFWxIEbjO2tkyPR6GoKI0pIDgctKsPVB+Wg6D+CbQ0= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.0 h1:p98vKnS4KzdgU/+vrVKFY3y9n9v1Z6cpo4JvbTNRxlM= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.0/go.mod h1:LNJJdteQG4E2fhWDerE+f8S2/ephEJg8yBkH1eqYYOo= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0 h1:F1iYRBwa0cZ2VHw8Zs4frqSWQ1B/tiCuSwH/DuHb8VM= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0/go.mod h1:3hAC5Ce0AOSt85BqD6DgTKNkJHmpXwqbwL8mVWRJQqo= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0 h1:mMeJvCQfZmakssvMyHjzp/ngxKysETDj9GJYhRwydzg= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0/go.mod h1:+paEFOL5IlJzhg9fy7/1+HSErVkWUgUj1ORLFwgvxnI= github.com/openstack-k8s-operators/lib-common/modules/storage v0.1.0 h1:rHn0wlwBBggRl65gWDniF97XW+1XB2+4PsGZS2RIJ5E= @@ -159,10 +151,6 @@ github.com/openstack-k8s-operators/manila-operator/api v0.1.0 h1:79TSB3A5+TLpK56 github.com/openstack-k8s-operators/manila-operator/api v0.1.0/go.mod h1:ywLIfMlreyF+19UNZw3ud84/Tlr4WffuopEUSXFTick= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.0 h1:oM0ZzFHHj+ioCc7NXHIO6+sy7I2yiN29DI9/jh4fe54= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.0/go.mod h1:m5XuZSa5Zt5uAw3WbJYOIkFAGXy01mybVekcKOq1qHI= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.0 h1:tGlQ4RPeFtgEHOnyqTnTzjzBaPHdpm0ieMMmQHl3XTg= -github.com/openstack-k8s-operators/neutron-operator/api v0.1.0/go.mod h1:5VaQboKxg4t65Xt1xcddjjODrUHkwQo9LCUWiGqbFao= -github.com/openstack-k8s-operators/nova-operator/api v0.1.1 h1:4FHCnUBopafOdnR+JEHyPROdi5wUjOk7G9YcfP3rfIE= -github.com/openstack-k8s-operators/nova-operator/api v0.1.1/go.mod h1:bQWyn3wTGEjbWk6qzyL7IhcIl9xU5WcGBcKBZZiD3Uo= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230801112207-bcd92ba349f6 h1:/shGXE4n0F99yX8eDPVzZwDL/lnM5Z/HhUhvBwxnWI8= github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-20230801112207-bcd92ba349f6/go.mod h1:SUnvwqdpvGNWSWe11yuu2M5Ns9FG0ge16tfNzwXmz/s= github.com/openstack-k8s-operators/openstack-ansibleee-operator/api v0.1.0 h1:M0WPgJ4ceFFg80amyOJY694zaMtovQyRN0AM0IuG8JA= @@ -171,8 +159,6 @@ github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.1.0 h1:Az github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.1.0/go.mod h1:BNOYX3F8NlBh73k2Utxlz+5o1DcZX76a3DY+WPMC31s= github.com/openstack-k8s-operators/ovn-operator/api v0.1.0 h1:AnmXOjUJMgxg8cRewjUIHfOCH1o3jTftYfvXiRGBjmA= github.com/openstack-k8s-operators/ovn-operator/api v0.1.0/go.mod h1:SSNSWIHTf2i/yM2KprT7FZeCuQfGwEf5eHnISi3zMAg= -github.com/openstack-k8s-operators/placement-operator/api v0.1.0 h1:i2UEgkyAommKa3Q3KOwQirbbiLW6EocS457S+3fc46s= -github.com/openstack-k8s-operators/placement-operator/api v0.1.0/go.mod h1:HTgKM7NBqtBKsCQaBbtF9xqNAjLAmaCGoFlCDmIu9I0= github.com/openstack-k8s-operators/swift-operator/api v0.1.0 h1:4d6o+qFzkm9vmIBiizjnL2D6QCqOIv8YTFVbWK7Dg20= github.com/openstack-k8s-operators/swift-operator/api v0.1.0/go.mod h1:7Ysj6252KjltNccUosTKbtBhw9NZ+Sys2esq0bKm18M= github.com/openstack-k8s-operators/telemetry-operator/api v0.1.0 h1:HF3SeZ3x6pbZrLxCmRkF+rIbaV8lISpA3gd2NCqX8D4= @@ -214,6 +200,20 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stuggi/cinder-operator/api v0.0.0-20230808075052-d7ecd3000e0a h1:Evy/ItVvgR94Wwlo7o7f2V3DbluJD4AIyFYUGyPNjso= +github.com/stuggi/cinder-operator/api v0.0.0-20230808075052-d7ecd3000e0a/go.mod h1:NiERYYJ4YYbxg2Ry5HyH+UI8pbvKap5GoZtW6Exk1pQ= +github.com/stuggi/glance-operator/api v0.0.0-20230808075207-6b14ed16b49b h1:YRBQHekvk9NHhbNOmNbR0OJZO48RizCfaQ6VyP960y4= +github.com/stuggi/glance-operator/api v0.0.0-20230808075207-6b14ed16b49b/go.mod h1:LD5Y1/RQInUqzluF7RtzPLuOeQjgfq7ek9ecPSkVvWw= +github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4 h1:qVwSTi3ZDWl8ITLcVBOwJlEDlMi3UyFykZh5qN76BSI= +github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4/go.mod h1:XdvO78DPVkkGFf5kPLDDb7a8/DGuv/JwxzhmipalUhw= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 h1:E5EGKIZHyAV1oofcXkcUq4NZfTtgFjjKpU6A0Yv2vls= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= +github.com/stuggi/neutron-operator/api v0.0.0-20230807133748-6ed1a0824e3a h1:cWcjdBMFPUg8+JOVVPY+WhKolV/McZIkHscqzDozkvM= +github.com/stuggi/neutron-operator/api v0.0.0-20230807133748-6ed1a0824e3a/go.mod h1:1RwvmP2LrLj/OJvSEl7hu3aYekB1EI79D1p/rfDxDZU= +github.com/stuggi/nova-operator/api v0.0.0-20230808075321-5f810c0dcaa0 h1:7zZX5Pu6Vlc2TLJs4arZK9wndIkeVUzFXjkeNIH8QL0= +github.com/stuggi/nova-operator/api v0.0.0-20230808075321-5f810c0dcaa0/go.mod h1:3Iin2b6jhn6ofsnUhl+WL3KQmC+QpDuimacCZZSUFIw= +github.com/stuggi/placement-operator/api v0.0.0-20230808075127-11794bf73d00 h1:UN2rIEvde98erkUPSUL/5j5KoshueEZZziVvG3d2RVo= +github.com/stuggi/placement-operator/api v0.0.0-20230808075127-11794bf73d00/go.mod h1:tg7n4eZXA5atHBLkUqSvD6EK3omwVN7fa5CSLZNBkFs= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= diff --git a/main.go b/main.go index d3fb2fb99..c9b3f8d0e 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" @@ -99,6 +100,7 @@ func init() { utilruntime.Must(telemetryv1.AddToScheme(scheme)) utilruntime.Must(swiftv1.AddToScheme(scheme)) utilruntime.Must(clientv1.AddToScheme(scheme)) + utilruntime.Must(routev1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/pkg/openstack/common.go b/pkg/openstack/common.go index 760a87c0a..a3570ef9e 100644 --- a/pkg/openstack/common.go +++ b/pkg/openstack/common.go @@ -2,11 +2,28 @@ package openstack import ( "context" + "fmt" + "strings" + "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" + corev1beta1 "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/apimachinery/pkg/runtime" + "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/reconcile" ) // EnsureDeleted - Delete the object which in turn will clean the sub resources @@ -27,3 +44,277 @@ func EnsureDeleted(ctx context.Context, helper *helper.Helper, obj client.Object return ctrl.Result{}, nil } + +// GetExternalEnpointDetailsForEndpoint - returns the MetalLBData for the endpoint, if not specified nil. +func GetExternalEnpointDetailsForEndpoint( + externalEndpoints []corev1.MetalLBConfig, + endpt service.Endpoint, +) *corev1.MetalLBConfig { + for _, metallbcfg := range externalEndpoints { + if metallbcfg.Endpoint == endpt { + return metallbcfg.DeepCopy() + } + } + + return nil +} + +// ServiceDetails - service details to create service.Service with overrides +type ServiceDetails struct { + ServiceName string + Namespace string + Endpoint service.Endpoint + ExternalEndpoints []corev1.MetalLBConfig + ServiceOverrideSpec []service.OverrideSpec + RouteOverrideSpec *route.OverrideSpec + endpointName string + endpointURL string + baseServiceLabels map[string]string + serviceLabels map[string]string + hostname *string + route *routev1.Route +} + +// GetServiceLabels - returns the labels for the service, used as selector on the route +func (sd *ServiceDetails) GetServiceLabels() map[string]string { + return sd.serviceLabels +} + +// GetEndpointName - returns the name of the endpoint +func (sd *ServiceDetails) GetEndpointName() string { + return sd.endpointName +} + +// GetEndpointURL - returns the URL of the endpoint (proto://hostname/path) +func (sd *ServiceDetails) GetEndpointURL() string { + return sd.endpointURL +} + +// public endpoint +// 1) Default (service override nil, no definition for public endpt in externalEndpoints) +// - create route + pass in service selector +// 2) externalEndpoints != nil for public endpt +// - pass in override for metallb LoadBalancer service +// 3) service override provided == LoadBalancer service type +// - do nothing let the service operator handle it +// 4) service override provided == ClusterIP service type +// - create route , merge override with service selector +// +// internal endpoint +// 1) Default (service override nil, no definition for public endpt in externalEndpoints) +// - service operator will create default service +// 2) externalEndpoints != nil for internal endpt, no service override provided +// - pass in override for metallb LoadBalancer service +// 3) externalEndpoints != nil for internal endpt, service override provided +// - merge override with metallb service and pass in override +// 4) externalEndpoints == nil for internal endpt, service override provided +// - do nothing let the service operator handle it + +// CreateEndpointServiceOverride - +func (sd *ServiceDetails) CreateEndpointServiceOverride() (*service.Service, error) { + + // set the endpoint name to service name - endpoint type + sd.endpointName = sd.ServiceName + "-" + string(sd.Endpoint) + + // create the service label + sd.baseServiceLabels = map[string]string{ + common.AppSelector: sd.ServiceName, + } + + // create the label for the service , used for the route -> service connection + sd.serviceLabels = util.MergeStringMaps( + sd.baseServiceLabels, + map[string]string{ + string(sd.Endpoint): "true", + }, + ) + + // initialize the service override if not specified via the CR + svcOverride := service.GetOverrideSpecForEndpoint(sd.ServiceOverrideSpec, sd.Endpoint).DeepCopy() + if svcOverride == nil { + svcOverride = &service.OverrideSpec{} + svcOverride.Endpoint = sd.Endpoint + } + + // get MetalLB config data for the endpoint + metalLBData := GetExternalEnpointDetailsForEndpoint(sd.ExternalEndpoints, sd.Endpoint) + + // Create generic service definitions for either MetalLB, or generic service + svcDef := &k8s_corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: sd.endpointName, + Namespace: sd.Namespace, + Labels: sd.serviceLabels, + }, + Spec: k8s_corev1.ServiceSpec{ + Type: k8s_corev1.ServiceTypeClusterIP, + }, + } + + // if the externalEndpoints is configured for the service and for this endpoint provided, + // set MetalLB annotations and service type to LoadBalancer + if metalLBData != nil { + // create MetalLB service definition + annotations := map[string]string{ + service.MetalLBAddressPoolAnnotation: metalLBData.IPAddressPool, + } + if len(metalLBData.LoadBalancerIPs) > 0 { + annotations[service.MetalLBLoadBalancerIPs] = strings.Join(metalLBData.LoadBalancerIPs, ",") + } + if metalLBData.SharedIP { + if metalLBData.SharedIPKey == "" { + annotations[service.MetalLBAllowSharedIPAnnotation] = metalLBData.IPAddressPool + } else { + annotations[service.MetalLBAllowSharedIPAnnotation] = metalLBData.SharedIPKey + } + } + svcDef.Annotations = annotations + svcDef.Spec.Type = k8s_corev1.ServiceTypeLoadBalancer + } + + // Create the service + svc, err := service.NewService( + svcDef, + time.Duration(5)*time.Second, //not really required as we don't create the service here + svcOverride, + ) + if err != nil { + return nil, err + } + + // add annotation to register service name in dnsmasq if it is a LoadBalancer service + if svc.GetServiceType() == k8s_corev1.ServiceTypeLoadBalancer { + svc.AddAnnotation(map[string]string{ + service.AnnotationHostnameKey: svc.GetServiceHostname(), + }) + } + + return svc, nil +} + +// CreateRoute - +func (sd *ServiceDetails) CreateRoute( + ctx context.Context, + helper *helper.Helper, + svc service.Service, +) (ctrl.Result, error) { + // TODO TLS + route, err := route.NewRoute( + route.GenericRoute(&route.GenericRouteDetails{ + Name: sd.ServiceName, + Namespace: sd.Namespace, + Labels: sd.baseServiceLabels, + ServiceName: sd.endpointName, + TargetPortName: sd.endpointName, + }), + time.Duration(5)*time.Second, + sd.RouteOverrideSpec, + ) + if err != nil { + return ctrl.Result{}, err + } + + ctrlResult, err := route.CreateOrPatch(ctx, helper) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + sd.hostname = pointer.String(route.GetHostname()) + sd.endpointURL = "http://" + *sd.hostname + sd.route = route.GetRoute() + + return ctrl.Result{}, nil +} + +// AddOwnerRef - adds owner to the OwnerReference list of the route +// Add the service CR to the ownerRef list of the route to prevent the route being deleted +// before the service is deleted. Otherwise this can result cleanup issues which require +// the endpoint to be reachable. +// If ALL objects in the list have been deleted, this object will be garbage collected. +// https://github.com/kubernetes/apimachinery/blob/15d95c0b2af3f4fcf46dce24105e5fbb9379af5a/pkg/apis/meta/v1/types.go#L240-L247 +func (sd *ServiceDetails) AddOwnerRef( + ctx context.Context, + helper *helper.Helper, + owner metav1.Object, + scheme *runtime.Scheme, +) error { + if sd.route != nil { + op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), sd.route, func() error { + err := controllerutil.SetOwnerReference(owner, sd.route, scheme) + if err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + if op != controllerutil.OperationResultNone { + helper.GetLogger().Info(fmt.Sprintf("%s route %s - %s", sd.ServiceName, sd.route.Name, op)) + } + } + + return nil +} + +// CreateRouteAndServiceOverride - +func (sd *ServiceDetails) CreateRouteAndServiceOverride( + ctx context.Context, + instance *corev1.OpenStackControlPlane, + helper *helper.Helper, + endpointType service.Endpoint, +) (*service.OverrideSpec, ctrl.Result, error) { + + svc, err := sd.CreateEndpointServiceOverride() + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + corev1beta1.OpenStackControlPlaneServiceOverrideReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + corev1beta1.OpenStackControlPlaneServiceOverrideReadyErrorMessage, + sd.ServiceName, + string(endpointType), + err.Error())) + + return nil, ctrl.Result{}, err + } + + // Create the route if it is public endpoint and the service type is ClusterIP + if svc != nil && sd.Endpoint == service.EndpointPublic && + svc.GetServiceType() == k8s_corev1.ServiceTypeClusterIP { + //TODO create TLS cert + var ctrlResult reconcile.Result + // + ctrlResult, err = sd.CreateRoute(ctx, helper, *svc) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.ExposeServiceReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.ExposeServiceReadyErrorMessage, + err.Error())) + return nil, ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return nil, ctrlResult, nil + } + + instance.Status.Conditions.MarkTrue(condition.ExposeServiceReadyCondition, condition.ExposeServiceReadyMessage) + } + + svcOverride := &service.OverrideSpec{ + Endpoint: sd.Endpoint, + EmbeddedLabelsAnnotations: &service.EmbeddedLabelsAnnotations{ + Annotations: svc.GetAnnotations(), + Labels: svc.GetLabels(), + }, + Spec: svc.GetSpec(), + } + + if sd.GetEndpointURL() != "" { + svcOverride.EndpointURL = pointer.String(sd.GetEndpointURL()) + } + + return svcOverride, ctrl.Result{}, nil +} diff --git a/pkg/openstack/keystone.go b/pkg/openstack/keystone.go index b84846c9b..e50b72640 100644 --- a/pkg/openstack/keystone.go +++ b/pkg/openstack/keystone.go @@ -12,11 +12,17 @@ import ( keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ctrl "sigs.k8s.io/controller-runtime" + + "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" ) // ReconcileKeystoneAPI - func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackControlPlane, helper *helper.Helper) (ctrl.Result, error) { + keystoneAPI := &keystonev1.KeystoneAPI{ ObjectMeta: metav1.ObjectMeta{ Name: "keystone", //FIXME (keystone doesn't seem to work unless named "keystone") @@ -32,9 +38,48 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo return ctrl.Result{}, nil } + // Create service overrides to pass into the service CR + // and expose the public endpoint using a route per default. + // Any trailing path will be added on the service-operator level. + var endpoints = map[service.Endpoint]endpoint.Data{ + service.EndpointPublic: {}, + service.EndpointInternal: {}, + } + serviceOverrides := []service.OverrideSpec{} + serviceDetails := []ServiceDetails{} + + for endpointType := range endpoints { + + sd := ServiceDetails{ + ServiceName: keystoneAPI.Name, + Namespace: instance.Namespace, + Endpoint: endpointType, + ExternalEndpoints: instance.Spec.Keystone.APIOverride.ExternalEndpoints, + ServiceOverrideSpec: instance.Spec.Keystone.Template.Override.Service, + RouteOverrideSpec: instance.Spec.Keystone.APIOverride.Route, + } + + svcOverride, ctrlResult, err := sd.CreateRouteAndServiceOverride(ctx, instance, helper, endpointType) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + serviceDetails = append( + serviceDetails, + sd, + ) + if svcOverride != nil { + serviceOverrides = append(serviceOverrides, *svcOverride) + } + instance.Status.Conditions.MarkTrue(corev1beta1.OpenStackControlPlaneServiceOverrideReadyCondition, corev1beta1.OpenStackControlPlaneServiceOverrideReadyMessage) + } + 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) + keystoneAPI.Spec.Override.Service = serviceOverrides if keystoneAPI.Spec.Secret == "" { keystoneAPI.Spec.Secret = instance.Spec.Secret } @@ -75,6 +120,28 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo corev1beta1.OpenStackControlPlaneKeystoneAPIReadyRunningMessage)) } + for _, sd := range serviceDetails { + // Add the service CR to the ownerRef list of the route to prevent the route being deleted + // before the service is deleted. Otherwise this can result cleanup issues which require + // the endpoint to be reachable. + // If ALL objects in the list have been deleted, this object will be garbage collected. + // https://github.com/kubernetes/apimachinery/blob/15d95c0b2af3f4fcf46dce24105e5fbb9379af5a/pkg/apis/meta/v1/types.go#L240-L247 + scheme := runtime.NewScheme() + gvk := schema.GroupVersionKind{ + Group: keystonev1.GroupVersion.Group, + Version: keystonev1.GroupVersion.Version, + Kind: keystoneAPI.Kind, + } + + // Add the GVK to the scheme + scheme.AddKnownTypeWithName(gvk, &keystonev1.KeystoneAPI{}) + + err = sd.AddOwnerRef(ctx, helper, keystoneAPI, scheme) + if err != nil { + return ctrl.Result{}, err + } + } + return ctrl.Result{}, nil }