From 99828bddbbf7d03570d692e0415cc1242c4e1436 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Tue, 1 Aug 2023 11:34:41 +0200 Subject: [PATCH] Create glanceapi 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 Depends-On: openstack-k8s-operators/glance-operator#285 Jira: OSP-26690 --- ....openstack.org_openstackcontrolplanes.yaml | 409 +++++++++++++++--- .../v1beta1/openstackcontrolplane_types.go | 13 + apis/core/v1beta1/zz_generated.deepcopy.go | 28 ++ apis/go.mod | 8 +- apis/go.sum | 12 +- ....openstack.org_openstackcontrolplanes.yaml | 409 +++++++++++++++--- ...nstack-operator.clusterserviceversion.yaml | 18 + go.mod | 8 +- go.sum | 12 +- pkg/openstack/glance.go | 92 ++++ 10 files changed, 889 insertions(+), 120 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index f27024429..4b8490243 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -2093,6 +2093,133 @@ spec: enabled: default: true type: boolean + 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 + override: + 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: containerImage: @@ -2894,32 +3021,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 +3029,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 +3206,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,6 +3214,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: diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 3fadb84a6..2327b7a58 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -229,6 +229,19 @@ type GlanceSection struct { //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Glance Service Template glancev1.GlanceSpec `json:"template,omitempty"` + + // ExternalEndpoints, expose a VIP using a pre-created IPAddressPool + ExternalEndpoints []MetalLBConfig `json:"externalEndpoints,omitempty"` + + // +kubebuilder:validation:Optional + // Override, provides the ability to override the generated manifest of several child resources. + Override GlanceOverrideSpec `json:"override,omitempty"` +} + +// GlanceOverrideSpec to override the generated manifest of several child resources. +type GlanceOverrideSpec struct { + // +kubebuilder:validation:Optional + Route *route.OverrideSpec `json:"route,omitempty"` } // CinderSection defines the desired state of Cinder service diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index dd345f2ba..29e0142f7 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -101,10 +101,38 @@ func (in *GaleraSection) DeepCopy() *GaleraSection { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlanceOverrideSpec) DeepCopyInto(out *GlanceOverrideSpec) { + *out = *in + if in.Route != nil { + in, out := &in.Route, &out.Route + *out = new(route.OverrideSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlanceOverrideSpec. +func (in *GlanceOverrideSpec) DeepCopy() *GlanceOverrideSpec { + if in == nil { + return nil + } + out := new(GlanceOverrideSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GlanceSection) DeepCopyInto(out *GlanceSection) { *out = *in in.Template.DeepCopyInto(&out.Template) + if in.ExternalEndpoints != nil { + in, out := &in.ExternalEndpoints, &out.ExternalEndpoints + *out = make([]MetalLBConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Override.DeepCopyInto(&out.Override) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlanceSection. diff --git a/apis/go.mod b/apis/go.mod index 518008430..3c10bf516 100644 --- a/apis/go.mod +++ b/apis/go.mod @@ -101,10 +101,14 @@ require ( // 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-20230801084758-6169f85dea1d +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20230801104002-92877b5235ca //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-20230801072240-78012cee7ee6 +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20230801105313-4b3881d64acb //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-20230801105440-8a4fb9c0ba1f diff --git a/apis/go.sum b/apis/go.sum index a34ef9961..a78bff9c3 100644 --- a/apis/go.sum +++ b/apis/go.sum @@ -128,8 +128,6 @@ github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxC 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= @@ -191,10 +189,12 @@ 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/keystone-operator/api v0.0.0-20230801072240-78012cee7ee6 h1:AGAL1xVaiufVo765y5uRKb/zOWw/M78hAOsdSy7nZuo= -github.com/stuggi/keystone-operator/api v0.0.0-20230801072240-78012cee7ee6/go.mod h1:fMstyYIgZTTLLO9q2jya/aF9ay4CedCLc9Mb6eXsxaA= -github.com/stuggi/lib-common/modules/common v0.0.0-20230801084758-6169f85dea1d h1:7yXrIPpHM0hYy6YQxbv6UHO7GUm36QE/DW2Hg4abSv4= -github.com/stuggi/lib-common/modules/common v0.0.0-20230801084758-6169f85dea1d/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= +github.com/stuggi/glance-operator/api v0.0.0-20230801105440-8a4fb9c0ba1f h1:O3vmG+0TTwC54wPz5BbxMp+JIVNVH5LqkpBpz+4V3Yc= +github.com/stuggi/glance-operator/api v0.0.0-20230801105440-8a4fb9c0ba1f/go.mod h1:IHc9zIcg6S8AjDxaPppuEt0lMdrp4w8OSRaLqG/30M0= +github.com/stuggi/keystone-operator/api v0.0.0-20230801105313-4b3881d64acb h1:kn6BkRCpDPoWo56QLynak4PtQdFGgFiRBsjk90T5SRI= +github.com/stuggi/keystone-operator/api v0.0.0-20230801105313-4b3881d64acb/go.mod h1:ldvLuOIfibv3Q/0Rmx7yL9wrVTmAnypS4s6Y3tw5Zng= +github.com/stuggi/lib-common/modules/common v0.0.0-20230801104002-92877b5235ca h1:cmCILWNMZ/Z7EuOPl7EPn+e8c2Iv5EXJ4B6YSqkBn9I= +github.com/stuggi/lib-common/modules/common v0.0.0-20230801104002-92877b5235ca/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= 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 f27024429..4b8490243 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -2093,6 +2093,133 @@ spec: enabled: default: true type: boolean + 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 + override: + 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: containerImage: @@ -2894,32 +3021,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 +3029,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 +3206,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,6 +3214,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: diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index f7f922ef0..dd05c3de1 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -81,6 +81,24 @@ spec: path: glance.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool + displayName: IPAddress Pool + path: glance.externalEndpoints[0].ipAddressPool + - description: LoadBalancerIPs, request given IPs from the pool if available. + Using a list to allow dual stack (IPv4/IPv6) support + displayName: Load Balancer IPs + path: glance.externalEndpoints[0].loadBalancerIPs + - description: SharedIP if true, VIP/VIPs get shared with multiple services + displayName: Shared IP + path: glance.externalEndpoints[0].sharedIP + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: SharedIPKey specifies the sharing key which gets set as the annotation + on the LoadBalancer service. Services which share the same VIP must have + the same SharedIPKey. Defaults to the IPAddressPool if SharedIP is true, + but no SharedIPKey specified. + displayName: Shared IPKey + path: glance.externalEndpoints[0].sharedIPKey - description: Template - Overrides to use when creating the Glance Service displayName: Template path: glance.template diff --git a/go.mod b/go.mod index ab9671fc0..0d6cc7bdc 100644 --- a/go.mod +++ b/go.mod @@ -113,10 +113,14 @@ replace github.com/openstack-k8s-operators/openstack-operator/apis => ./apis // 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-20230801084758-6169f85dea1d +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20230801104002-92877b5235ca //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-20230801072240-78012cee7ee6 +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20230801105313-4b3881d64acb //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-20230801105440-8a4fb9c0ba1f diff --git a/go.sum b/go.sum index 30386b19f..afe5eda38 100644 --- a/go.sum +++ b/go.sum @@ -137,8 +137,6 @@ github.com/openstack-k8s-operators/cinder-operator/api v0.1.0 h1:8QsJidoozdGsV9f 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.20230731222534-a2e91a5bf076 h1:QgvGAU4kJoQamnQlXe2nTiEqx62sY0xDZxq+jvCXOHs= github.com/openstack-k8s-operators/dataplane-operator/api v0.1.1-0.20230731222534-a2e91a5bf076/go.mod h1:5qvkN87pvsGz3LyTM/muQ22u3TrY72ZR7JzI84QHI/w= -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= @@ -208,10 +206,12 @@ 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/keystone-operator/api v0.0.0-20230801072240-78012cee7ee6 h1:AGAL1xVaiufVo765y5uRKb/zOWw/M78hAOsdSy7nZuo= -github.com/stuggi/keystone-operator/api v0.0.0-20230801072240-78012cee7ee6/go.mod h1:fMstyYIgZTTLLO9q2jya/aF9ay4CedCLc9Mb6eXsxaA= -github.com/stuggi/lib-common/modules/common v0.0.0-20230801084758-6169f85dea1d h1:7yXrIPpHM0hYy6YQxbv6UHO7GUm36QE/DW2Hg4abSv4= -github.com/stuggi/lib-common/modules/common v0.0.0-20230801084758-6169f85dea1d/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= +github.com/stuggi/glance-operator/api v0.0.0-20230801105440-8a4fb9c0ba1f h1:O3vmG+0TTwC54wPz5BbxMp+JIVNVH5LqkpBpz+4V3Yc= +github.com/stuggi/glance-operator/api v0.0.0-20230801105440-8a4fb9c0ba1f/go.mod h1:IHc9zIcg6S8AjDxaPppuEt0lMdrp4w8OSRaLqG/30M0= +github.com/stuggi/keystone-operator/api v0.0.0-20230801105313-4b3881d64acb h1:kn6BkRCpDPoWo56QLynak4PtQdFGgFiRBsjk90T5SRI= +github.com/stuggi/keystone-operator/api v0.0.0-20230801105313-4b3881d64acb/go.mod h1:ldvLuOIfibv3Q/0Rmx7yL9wrVTmAnypS4s6Y3tw5Zng= +github.com/stuggi/lib-common/modules/common v0.0.0-20230801104002-92877b5235ca h1:cmCILWNMZ/Z7EuOPl7EPn+e8c2Iv5EXJ4B6YSqkBn9I= +github.com/stuggi/lib-common/modules/common v0.0.0-20230801104002-92877b5235ca/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= 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/pkg/openstack/glance.go b/pkg/openstack/glance.go index 5decc025b..bdbc32db6 100644 --- a/pkg/openstack/glance.go +++ b/pkg/openstack/glance.go @@ -5,13 +5,17 @@ import ( "fmt" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" "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" glancev1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime" ) @@ -32,9 +36,97 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl return ctrl.Result{}, nil } + spec := instance.Spec.Glance.DeepCopy() + + // Create service overrides to pass into the service CR + // and expose the public endpoint using a route per default + var endpoints = map[service.Endpoint]endpoint.Data{ + service.EndpointPublic: {}, + service.EndpointInternal: {}, + } + + serviceOverrides := []service.OverrideSpec{} + + serviceOverrideSpec := []service.OverrideSpec{} + if spec.Template.GlanceAPIExternal.Override.Service != nil { + serviceOverrideSpec = append(serviceOverrideSpec, *spec.Template.GlanceAPIExternal.Override.Service) + } + if spec.Template.GlanceAPIInternal.Override.Service != nil { + serviceOverrideSpec = append(serviceOverrideSpec, *spec.Template.GlanceAPIInternal.Override.Service) + } + + for endpointType := range endpoints { + + sd := ServiceDetails{ + ServiceName: glance.Name, + Namespace: instance.Namespace, + Endpoint: endpointType, + ExternalEndpoints: spec.ExternalEndpoints, + ServiceOverrideSpec: serviceOverrideSpec, + RouteOverrideSpec: spec.Override.Route, + } + + svc, err := sd.CreateEndpointServiceOverride() + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + // TODO new ServiceOverrideCondition + condition.ExposeServiceReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.ExposeServiceReadyErrorMessage, + err.Error())) + + return 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() == corev1.ServiceTypeClusterIP { + sd.CreateRoute(ctx, helper, *svc) + 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 ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + // set the URL for the endpoint. Any trailing path needs to be added by the service operator + // TODO: TLS, pass in https as protocol, create TLS cert + endpointProto := endpoint.EndptProtocol(endpoint.PtrProtocol(endpoint.ProtocolHTTP)) + sd.endpointURL, err = svc.GetAPIEndpoint(nil, endpointProto, "") + if err != nil { + return ctrl.Result{}, err + } + } + + 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()) + } + + serviceOverrides = append(serviceOverrides, svcOverride) + } + helper.GetLogger().Info("Reconciling Glance", "Glance.Namespace", instance.Namespace, "Glance.Name", "glance") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), glance, func() error { instance.Spec.Glance.Template.DeepCopyInto(&glance.Spec) + glance.Spec.GlanceAPIExternal.Override.Service = service.GetOverrideSpecForEndpoint(serviceOverrides, service.EndpointPublic).DeepCopy() + glance.Spec.GlanceAPIInternal.Override.Service = service.GetOverrideSpecForEndpoint(serviceOverrides, service.EndpointInternal).DeepCopy() + if glance.Spec.Secret == "" { glance.Spec.Secret = instance.Spec.Secret }