From 67d6e205f862066c78b3a4f25d3299295f0bd58c Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Tue, 12 Sep 2023 17:22:06 +0200 Subject: [PATCH] Create ironicapi and ironicinspector route and svc endpoint overrides Creates the route for the ironicapi and ironicinspector, 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: openstack-k8s-operators/lib-common#313 Depends-On: openstack-k8s-operators/keystone-operator#289 Depends-On: openstack-k8s-operators/ironic-operator#334 Jira: OSP-26690 --- ....openstack.org_openstackcontrolplanes.yaml | 356 +++++++++++++++--- apis/core/v1beta1/conditions.go | 3 + .../v1beta1/openstackcontrolplane_types.go | 10 + apis/core/v1beta1/zz_generated.deepcopy.go | 2 + ....openstack.org_openstackcontrolplanes.yaml | 356 +++++++++++++++--- ...nstack-operator.clusterserviceversion.yaml | 154 +++----- pkg/openstack/ironic.go | 93 +++++ 7 files changed, 775 insertions(+), 199 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 6e43a5872..40d52eeb3 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -4198,9 +4198,211 @@ spec: type: object ironic: properties: + apiOverride: + properties: + route: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + alternateBackends: + items: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + maxItems: 3 + type: array + host: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + path: + pattern: ^/ + type: string + port: + properties: + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - targetPort + type: object + subdomain: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + tls: + properties: + caCertificate: + type: string + certificate: + type: string + destinationCACertificate: + type: string + insecureEdgeTerminationPolicy: + type: string + key: + type: string + termination: + enum: + - edge + - reencrypt + - passthrough + type: string + required: + - termination + type: object + to: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + wildcardPolicy: + enum: + - None + - Subdomain + - "" + type: string + type: object + type: object + type: object enabled: default: false type: boolean + inspectorOverride: + properties: + route: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + alternateBackends: + items: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + maxItems: 3 + type: array + host: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + path: + pattern: ^/ + type: string + port: + properties: + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - targetPort + type: object + subdomain: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + tls: + properties: + caCertificate: + type: string + certificate: + type: string + destinationCACertificate: + type: string + insecureEdgeTerminationPolicy: + type: string + key: + type: string + termination: + enum: + - edge + - reencrypt + - passthrough + type: string + required: + - termination + type: object + to: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + wildcardPolicy: + enum: + - None + - Subdomain + - "" + type: string + type: object + type: object + type: object template: properties: customServiceConfig: @@ -4248,32 +4450,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 @@ -4282,6 +4458,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -4459,32 +4686,6 @@ spec: - start type: object type: array - 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 inspectionNetwork: type: string networkAttachments: @@ -4495,6 +4696,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: database: IronicInspectorDatabasePassword diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 826001c17..83ec892c9 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -78,6 +78,9 @@ const ( // OpenStackControlPlaneIronicReadyCondition Status=True condition which indicates if Ironic is configured and operational OpenStackControlPlaneIronicReadyCondition condition.Type = "OpenStackControlPlaneIronicReady" + // OpenStackControlPlaneExposeIronicReadyCondition Status=True condition which indicates if Ironic is exposed via a route + OpenStackControlPlaneExposeIronicReadyCondition condition.Type = "OpenStackControlPlaneExposeIronicReady" + // OpenStackControlPlaneHorizonReadyCondition Status=True condition which indicates if Horizon is configured and operational OpenStackControlPlaneHorizonReadyCondition condition.Type = "OpenStackControlPlaneHorizonReady" diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 0d72e2430..da052accb 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -444,6 +444,16 @@ type IronicSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Ironic services Template ironicv1.IronicSpec `json:"template,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // APIOverride, provides the ability to override the generated manifest of several child resources. + APIOverride Override `json:"apiOverride,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // InspectorOverride, provides the ability to override the generated manifest of several child resources. + InspectorOverride Override `json:"inspectorOverride,omitempty"` } // ManilaSection defines the desired state of Manila service diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 7279211bc..aaed21784 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -158,6 +158,8 @@ func (in *HorizonSection) DeepCopy() *HorizonSection { func (in *IronicSection) DeepCopyInto(out *IronicSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + in.APIOverride.DeepCopyInto(&out.APIOverride) + in.InspectorOverride.DeepCopyInto(&out.InspectorOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IronicSection. diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 6e43a5872..40d52eeb3 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -4198,9 +4198,211 @@ spec: type: object ironic: properties: + apiOverride: + properties: + route: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + alternateBackends: + items: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + maxItems: 3 + type: array + host: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + path: + pattern: ^/ + type: string + port: + properties: + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - targetPort + type: object + subdomain: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + tls: + properties: + caCertificate: + type: string + certificate: + type: string + destinationCACertificate: + type: string + insecureEdgeTerminationPolicy: + type: string + key: + type: string + termination: + enum: + - edge + - reencrypt + - passthrough + type: string + required: + - termination + type: object + to: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + wildcardPolicy: + enum: + - None + - Subdomain + - "" + type: string + type: object + type: object + type: object enabled: default: false type: boolean + inspectorOverride: + properties: + route: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + alternateBackends: + items: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + maxItems: 3 + type: array + host: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + path: + pattern: ^/ + type: string + port: + properties: + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - targetPort + type: object + subdomain: + maxLength: 253 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + tls: + properties: + caCertificate: + type: string + certificate: + type: string + destinationCACertificate: + type: string + insecureEdgeTerminationPolicy: + type: string + key: + type: string + termination: + enum: + - edge + - reencrypt + - passthrough + type: string + required: + - termination + type: object + to: + properties: + kind: + enum: + - Service + - "" + type: string + name: + type: string + weight: + format: int32 + maximum: 256 + minimum: 0 + type: integer + type: object + wildcardPolicy: + enum: + - None + - Subdomain + - "" + type: string + type: object + type: object + type: object template: properties: customServiceConfig: @@ -4248,32 +4450,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 @@ -4282,6 +4458,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object replicas: default: 1 format: int32 @@ -4459,32 +4686,6 @@ spec: - start type: object type: array - 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 inspectionNetwork: type: string networkAttachments: @@ -4495,6 +4696,57 @@ spec: additionalProperties: type: string type: object + override: + properties: + service: + additionalProperties: + properties: + endpointURL: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + externalName: + type: string + externalTrafficPolicy: + type: string + internalTrafficPolicy: + type: string + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + type: object + type: object passwordSelectors: default: database: IronicInspectorDatabasePassword diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index da7a64790..5ca7c61e7 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -37,29 +37,15 @@ spec: - description: Cinder - Parameters related to the Cinder service displayName: Cinder path: cinder + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: cinder.apiOverride - description: Enabled - Whether Cinder service should be deployed and managed displayName: Enabled path: cinder.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool - displayName: IPAddress Pool - path: cinder.externalEndpoints[0].ipAddressPool - - description: LoadBalancerIPs, request given IPs from the pool if available. - Using a list to allow dual stack (IPv4/IPv6) support - displayName: Load Balancer IPs - path: cinder.externalEndpoints[0].loadBalancerIPs - - description: SharedIP if true, VIP/VIPs get shared with multiple services - displayName: Shared IP - path: cinder.externalEndpoints[0].sharedIP - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: SharedIPKey specifies the sharing key which gets set as the annotation - on the LoadBalancer service. Services which share the same VIP must have - the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, - but no SharedIPKey specified. - displayName: Shared IPKey - path: cinder.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating Cinder Resources displayName: Template path: cinder.template @@ -94,35 +80,29 @@ spec: - description: Glance - Parameters related to the Glance service displayName: Glance path: glance + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: glance.apiOverride - description: Enabled - Whether Glance service should be deployed and managed displayName: Enabled path: glance.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool - displayName: IPAddress Pool - path: glance.externalEndpoints[0].ipAddressPool - - description: LoadBalancerIPs, request given IPs from the pool if available. - Using a list to allow dual stack (IPv4/IPv6) support - displayName: Load Balancer IPs - path: glance.externalEndpoints[0].loadBalancerIPs - - description: SharedIP if true, VIP/VIPs get shared with multiple services - displayName: Shared IP - path: glance.externalEndpoints[0].sharedIP - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: SharedIPKey specifies the sharing key which gets set as the annotation - on the LoadBalancer service. Services which share the same VIP must have - the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, - but no SharedIPKey specified. - displayName: Shared IPKey - path: glance.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating the Glance Service displayName: Template path: glance.template - description: Heat - Parameters related to the Heat services displayName: Heat path: heat + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: heat.apiOverride + - description: CnfAPIOverride, provides the ability to override the generated + manifest of several child resources. + displayName: Cnf APIOverride + path: heat.cnfAPIOverride - description: Enabled - Whether Heat services should be deployed and managed displayName: Enabled path: heat.enabled @@ -134,46 +114,48 @@ spec: - description: Horizon - Parameters related to the Horizon services displayName: Horizon path: horizon + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: horizon.apiOverride - description: Ironic - Parameters related to the Ironic services displayName: Ironic path: ironic + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: ironic.apiOverride - description: Enabled - Whether Ironic services should be deployed and managed displayName: Enabled path: ironic.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: InspectorOverride, provides the ability to override the generated + manifest of several child resources. + displayName: Inspector Override + path: ironic.inspectorOverride - description: Template - Overrides to use when creating the Ironic services displayName: Template path: ironic.template - description: Keystone - Parameters related to the Keystone service displayName: Keystone path: keystone + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: keystone.apiOverride - description: Enabled - Whether Keystone service should be deployed and managed displayName: Enabled 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 + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: manila.apiOverride - description: Enabled - Whether Manila service should be deployed and managed displayName: Enabled path: manila.enabled @@ -204,12 +186,16 @@ spec: - description: Neutron - Overrides to use when creating the Neutron Service displayName: Neutron path: neutron + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: neutron.apiOverride - description: Enabled - Whether Neutron service should be deployed and managed displayName: Enabled path: neutron.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Template - Overrides to use when creating the Neutron service + - description: Template - Overrides to use when creating the Neutron Service displayName: Template path: neutron.template - description: NodeSelector to target subset of worker nodes running control @@ -219,6 +205,16 @@ spec: - description: Nova - Parameters related to the Nova services displayName: Nova path: nova + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: nova.apiOverride + - description: CellOverride, provides the ability to override the generated + manifest of several child resources for a nova cell. cell0 never have compute + nodes and therefore it won't have a noVNCProxy deployed. Providing an override + for cell0 noVNCProxy does not have an effect. + displayName: Cell Override + path: nova.cellOverride - description: Enabled - Whether Nova services should be deployed and managed displayName: Enabled path: nova.enabled @@ -261,29 +257,15 @@ spec: - description: Placement - Parameters related to the Placement service displayName: Placement path: placement + - description: APIOverride, provides the ability to override the generated manifest + of several child resources. + displayName: APIOverride + path: placement.apiOverride - description: Enabled - Whether Placement service should be deployed and managed displayName: Enabled path: placement.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool - displayName: IPAddress Pool - path: placement.externalEndpoints[0].ipAddressPool - - description: LoadBalancerIPs, request given IPs from the pool if available. - Using a list to allow dual stack (IPv4/IPv6) support - displayName: Load Balancer IPs - path: placement.externalEndpoints[0].loadBalancerIPs - - description: SharedIP if true, VIP/VIPs get shared with multiple services - displayName: Shared IP - path: placement.externalEndpoints[0].sharedIP - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: SharedIPKey specifies the sharing key which gets set as the annotation - on the LoadBalancer service. Services which share the same VIP must have - the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, - but no SharedIPKey specified. - displayName: Shared IPKey - path: placement.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating the Placement API displayName: Template path: placement.template @@ -298,28 +280,6 @@ spec: - description: Templates - Overrides to use when creating the Rabbitmq clusters displayName: Templates path: rabbitmq.templates - - description: ExternalEndpoint, expose a VIP via MetalLB on the pre-created - address pool - displayName: External Endpoint - path: rabbitmq.templates.externalEndpoint - - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool - displayName: IPAddress Pool - path: rabbitmq.templates.externalEndpoint.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: rabbitmq.templates.externalEndpoint.loadBalancerIPs - - description: SharedIP if true, VIP/VIPs get shared with multiple services - displayName: Shared IP - path: rabbitmq.templates.externalEndpoint.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: rabbitmq.templates.externalEndpoint.sharedIPKey - description: 'Secret - FIXME: make this optional' displayName: Secret path: secret @@ -335,6 +295,10 @@ spec: path: swift.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: ProxyOverride, provides the ability to override the generated + manifest of several child resources. + displayName: Proxy Override + path: swift.proxyOverride - description: Template - Overrides to use when creating Swift Resources displayName: Template path: swift.template diff --git a/pkg/openstack/ironic.go b/pkg/openstack/ironic.go index d207ccb5e..b270c0f80 100644 --- a/pkg/openstack/ironic.go +++ b/pkg/openstack/ironic.go @@ -4,14 +4,20 @@ import ( "context" "fmt" + "github.com/openstack-k8s-operators/lib-common/modules/common" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/reconcile" ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" ) @@ -29,9 +35,96 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl return res, err } instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneIronicReadyCondition) + instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneExposeIronicReadyCondition) return ctrl.Result{}, nil } + // add selector to service overrides + for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { + if instance.Spec.Ironic.Template.IronicAPI.Override.Service == nil { + instance.Spec.Ironic.Template.IronicAPI.Override.Service = map[string]service.RoutedOverrideSpec{} + } + instance.Spec.Ironic.Template.IronicAPI.Override.Service[string(endpointType)] = + AddServiceComponentLabel( + ptr.To(instance.Spec.Ironic.Template.IronicAPI.Override.Service[string(endpointType)]), + ironic.Name+"-api") + + if instance.Spec.Ironic.Template.IronicInspector.Override.Service == nil { + instance.Spec.Ironic.Template.IronicInspector.Override.Service = map[string]service.RoutedOverrideSpec{} + } + instance.Spec.Ironic.Template.IronicInspector.Override.Service[string(endpointType)] = + AddServiceComponentLabel( + ptr.To(instance.Spec.Ironic.Template.IronicInspector.Override.Service[string(endpointType)]), + ironic.Name+"-inspector") + } + + // When component services got created check if there is the need to create a route + if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "ironic", Namespace: instance.Namespace}, ironic); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + + // Ironic API + if ironic.Status.Conditions.IsTrue(ironicv1.IronicAPIReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: ironic.Name + "-api"}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Ironic.Template.IronicAPI.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + ironic, + svcs, + instance.Spec.Ironic.Template.IronicAPI.Override.Service, + instance.Spec.Ironic.APIOverride.Route, + corev1beta1.OpenStackControlPlaneExposeIronicReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + + // Ironic Inspector + if ironic.Status.Conditions.IsTrue(ironicv1.IronicInspectorReadyCondition) { + svcs, err := service.GetServicesListWithLabel( + ctx, + helper, + instance.Namespace, + map[string]string{common.AppSelector: ironic.Name + "-inspector"}, + ) + if err != nil { + return ctrl.Result{}, err + } + + var ctrlResult reconcile.Result + instance.Spec.Ironic.Template.IronicInspector.Override.Service, ctrlResult, err = EnsureRoute( + ctx, + instance, + helper, + ironic, + svcs, + instance.Spec.Ironic.Template.IronicInspector.Override.Service, + instance.Spec.Ironic.InspectorOverride.Route, + corev1beta1.OpenStackControlPlaneExposeIronicReadyCondition, + ) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + helper.GetLogger().Info("Reconciling Ironic", "Ironic.Namespace", instance.Namespace, "Ironic.Name", "ironic") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), ironic, func() error { instance.Spec.Ironic.Template.DeepCopyInto(&ironic.Spec)