diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 01bb67a5f..d77b10b54 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -17,6 +17,8 @@ limitations under the License. package v1beta1 import ( + "fmt" + barbicanv1 "github.com/openstack-k8s-operators/barbican-operator/api/v1beta1" cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" designatev1 "github.com/openstack-k8s-operators/designate-operator/api/v1beta1" @@ -62,6 +64,9 @@ const ( OvnDbCaName = tls.DefaultCAPrefix + "ovn" // LibvirtCaName - LibvirtCaName = tls.DefaultCAPrefix + "libvirt" + + // GlanceName - Default Glance name + GlanceName = "glance" ) // OpenStackControlPlaneSpec defines the desired state of OpenStackControlPlane @@ -974,3 +979,14 @@ func (c CertConfig) GetRenewBeforeHours() string { return "" } + +// GetServiceName - returns the name and altName depending if +// UniquePodNames is configured +func (instance OpenStackControlPlane) GetServiceName(name string, uniquePodNames bool) (string, string) { + altName := fmt.Sprintf("%s-%s", name, instance.UID[:5]) + if uniquePodNames { + name, altName = altName, name + } + + return name, altName +} diff --git a/apis/core/v1beta1/openstackcontrolplane_webhook.go b/apis/core/v1beta1/openstackcontrolplane_webhook.go index e93930548..9ef8c7ef8 100644 --- a/apis/core/v1beta1/openstackcontrolplane_webhook.go +++ b/apis/core/v1beta1/openstackcontrolplane_webhook.go @@ -279,6 +279,14 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad } if r.Spec.Glance.Enabled { + glanceName, _ := r.GetServiceName(GlanceName, r.Spec.Glance.UniquePodNames) + for key, glanceAPI := range r.Spec.Glance.Template.GlanceAPIs { + err := common_webhook.ValidateDNS1123Label( + basePath.Child("glance").Child("template").Child("glanceAPIs"), + []string{key}, + glancev1.GetCrMaxLengthCorrection(glanceName, glanceAPI.Type)) // omit issue with statefulset pod label "controller-revision-hash": "-" + errors = append(errors, err...) + } errors = append(errors, r.Spec.Glance.Template.ValidateCreate(basePath.Child("glance").Child("template"))...) } @@ -390,6 +398,14 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Glance.Template == nil { old.Glance.Template = &glancev1.GlanceSpecCore{} } + glanceName, _ := r.GetServiceName(GlanceName, r.Spec.Glance.UniquePodNames) + for key, glanceAPI := range r.Spec.Glance.Template.GlanceAPIs { + err := common_webhook.ValidateDNS1123Label( + basePath.Child("glance").Child("template").Child("glanceAPIs"), + []string{key}, + glancev1.GetCrMaxLengthCorrection(glanceName, glanceAPI.Type)) // omit issue with statefulset pod label "controller-revision-hash": "-" + errors = append(errors, err...) + } errors = append(errors, r.Spec.Glance.Template.ValidateUpdate(*old.Glance.Template, basePath.Child("glance").Child("template"))...) } diff --git a/apis/go.mod b/apis/go.mod index 0d3b1da31..9c6e67a04 100644 --- a/apis/go.mod +++ b/apis/go.mod @@ -10,7 +10,7 @@ require ( github.com/openstack-k8s-operators/barbican-operator/api v0.4.1-0.20240715065052-b467a20b6696 github.com/openstack-k8s-operators/cinder-operator/api v0.4.1-0.20240709170501-8cdb9c68d2b2 github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240715084339-770038b9b19c - github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240714131453-8248cbbd71b0 + github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240719095750-570173dcbafb github.com/openstack-k8s-operators/heat-operator/api v0.4.1-0.20240715084339-1e2113ac57b7 github.com/openstack-k8s-operators/horizon-operator/api v0.4.1-0.20240715101812-a40a0701a6f4 github.com/openstack-k8s-operators/infra-operator/apis v0.4.1-0.20240716081244-6191389eafd5 diff --git a/apis/go.sum b/apis/go.sum index 399d40acf..1d1345169 100644 --- a/apis/go.sum +++ b/apis/go.sum @@ -96,8 +96,8 @@ github.com/openstack-k8s-operators/cinder-operator/api v0.4.1-0.20240709170501-8 github.com/openstack-k8s-operators/cinder-operator/api v0.4.1-0.20240709170501-8cdb9c68d2b2/go.mod h1:ALiHsN2QOlIMbeYT5zBT6y0T01qscpPqIlKoC4k2hf4= github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240715084339-770038b9b19c h1:6swKdKjtAOiCxm/Zn1r/zr+37QnqIDGIS4p3a4PJFyA= github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240715084339-770038b9b19c/go.mod h1:zEDytGmq4nHOsx/35YoYNxjGwCSg29/dUquVpTrWupQ= -github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240714131453-8248cbbd71b0 h1:0iXf/3mFndmXIQehVeQq1AXYqX6ueZn9wxOR9vaZIg4= -github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240714131453-8248cbbd71b0/go.mod h1:d5jIUULDakLoT0lM+wyR9ppdq/IrkWH97+mMufoDQcQ= +github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240719095750-570173dcbafb h1:lUo0jV+4i40upbruoyTlsUcsmNcJwPfi6uk0X6Oc6Wk= +github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240719095750-570173dcbafb/go.mod h1:7TSiTVXd2YruGwLJxqMyoqEzqilwi5PWcNqcGxt8AiA= github.com/openstack-k8s-operators/heat-operator/api v0.4.1-0.20240715084339-1e2113ac57b7 h1:uzSSMeDv/6izNbym2t2MUuUQ91/UN76yHA6blM08Rb8= github.com/openstack-k8s-operators/heat-operator/api v0.4.1-0.20240715084339-1e2113ac57b7/go.mod h1:VdfRsAYy7pAPH71QM5DPWk9t/Y+l+w+7n651zm9XnvU= github.com/openstack-k8s-operators/horizon-operator/api v0.4.1-0.20240715101812-a40a0701a6f4 h1:0tV5GXv9vmJdybZQxq15MQP+rO1LKNrdv92z2ra0+tg= diff --git a/go.mod b/go.mod index f69f7e628..c98630b28 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/openstack-k8s-operators/barbican-operator/api v0.4.1-0.20240715065052-b467a20b6696 github.com/openstack-k8s-operators/cinder-operator/api v0.4.1-0.20240709170501-8cdb9c68d2b2 github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240715084339-770038b9b19c - github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240714131453-8248cbbd71b0 + github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240719095750-570173dcbafb github.com/openstack-k8s-operators/heat-operator/api v0.4.1-0.20240715084339-1e2113ac57b7 github.com/openstack-k8s-operators/horizon-operator/api v0.4.1-0.20240715101812-a40a0701a6f4 github.com/openstack-k8s-operators/infra-operator/apis v0.4.1-0.20240716081244-6191389eafd5 diff --git a/go.sum b/go.sum index 80246ed91..8a3dfd97c 100644 --- a/go.sum +++ b/go.sum @@ -104,8 +104,8 @@ github.com/openstack-k8s-operators/cinder-operator/api v0.4.1-0.20240709170501-8 github.com/openstack-k8s-operators/cinder-operator/api v0.4.1-0.20240709170501-8cdb9c68d2b2/go.mod h1:ALiHsN2QOlIMbeYT5zBT6y0T01qscpPqIlKoC4k2hf4= github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240715084339-770038b9b19c h1:6swKdKjtAOiCxm/Zn1r/zr+37QnqIDGIS4p3a4PJFyA= github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240715084339-770038b9b19c/go.mod h1:zEDytGmq4nHOsx/35YoYNxjGwCSg29/dUquVpTrWupQ= -github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240714131453-8248cbbd71b0 h1:0iXf/3mFndmXIQehVeQq1AXYqX6ueZn9wxOR9vaZIg4= -github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240714131453-8248cbbd71b0/go.mod h1:d5jIUULDakLoT0lM+wyR9ppdq/IrkWH97+mMufoDQcQ= +github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240719095750-570173dcbafb h1:lUo0jV+4i40upbruoyTlsUcsmNcJwPfi6uk0X6Oc6Wk= +github.com/openstack-k8s-operators/glance-operator/api v0.4.1-0.20240719095750-570173dcbafb/go.mod h1:7TSiTVXd2YruGwLJxqMyoqEzqilwi5PWcNqcGxt8AiA= github.com/openstack-k8s-operators/heat-operator/api v0.4.1-0.20240715084339-1e2113ac57b7 h1:uzSSMeDv/6izNbym2t2MUuUQ91/UN76yHA6blM08Rb8= github.com/openstack-k8s-operators/heat-operator/api v0.4.1-0.20240715084339-1e2113ac57b7/go.mod h1:VdfRsAYy7pAPH71QM5DPWk9t/Y+l+w+7n651zm9XnvU= github.com/openstack-k8s-operators/horizon-operator/api v0.4.1-0.20240715101812-a40a0701a6f4 h1:0tV5GXv9vmJdybZQxq15MQP+rO1LKNrdv92z2ra0+tg= diff --git a/pkg/openstack/glance.go b/pkg/openstack/glance.go index 7b8024a30..d5bec7b99 100644 --- a/pkg/openstack/glance.go +++ b/pkg/openstack/glance.go @@ -28,11 +28,7 @@ const ( // ReconcileGlance - func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControlPlane, version *corev1beta1.OpenStackVersion, helper *helper.Helper) (ctrl.Result, error) { - glanceName := "glance" - altGlanceName := fmt.Sprintf("glance-%s", instance.UID[:5]) - if instance.Spec.Glance.UniquePodNames { - glanceName, altGlanceName = altGlanceName, glanceName - } + glanceName, altGlanceName := instance.GetServiceName(corev1beta1.GlanceName, instance.Spec.Glance.UniquePodNames) // Ensure the alternate cinder CR doesn't exist, as the ramdomPodNames flag may have been toggled glance := &glancev1.Glance{ ObjectMeta: metav1.ObjectMeta{ diff --git a/tests/functional/ctlplane/openstackoperator_controller_test.go b/tests/functional/ctlplane/openstackoperator_controller_test.go index 5af882b9e..c6277f2b9 100644 --- a/tests/functional/ctlplane/openstackoperator_controller_test.go +++ b/tests/functional/ctlplane/openstackoperator_controller_test.go @@ -2011,4 +2011,138 @@ var _ = Describe("OpenStackOperator Webhook", func() { "Invalid value: \"foo_bar\": a lowercase RFC 1123 label must consist"), ) }) + + It("Blocks creating ctlplane CRs with to long glanceapi keys/names", func() { + spec := GetDefaultOpenStackControlPlaneSpec() + + apiList := map[string]interface{}{ + "foo-1234567890-1234567890-1234567890-1234567890-1234567890": map[string]interface{}{ + "replicas": 1, + }, + } + + glanceTemplate := map[string]interface{}{ + "databaseInstance": "openstack", + "secret": "secret", + "databaseAccount": "account", + "glanceAPIs": apiList, + } + + spec["glance"] = map[string]interface{}{ + "enabled": true, + "uniquePodNames": false, + "template": glanceTemplate, + } + + raw := map[string]interface{}{ + "apiVersion": "core.openstack.org/v1beta1", + "kind": "OpenStackControlPlane", + "metadata": map[string]interface{}{ + "name": "foo", + "namespace": namespace, + }, + "spec": spec, + } + + unstructuredObj := &unstructured.Unstructured{Object: raw} + _, err := controllerutil.CreateOrPatch( + th.Ctx, th.K8sClient, unstructuredObj, func() error { return nil }) + Expect(err).Should(HaveOccurred()) + var statusError *k8s_errors.StatusError + Expect(errors.As(err, &statusError)).To(BeTrue()) + Expect(statusError.ErrStatus.Details.Kind).To(Equal("OpenStackControlPlane")) + Expect(statusError.ErrStatus.Message).To( + ContainSubstring( + "Invalid value: \"foo-1234567890-1234567890-1234567890-1234567890-1234567890\": must be no more than 39 characters"), + ) + }) + + It("Blocks creating ctlplane CRs with to long glanceapi keys/names (uniquePodNames)", func() { + spec := GetDefaultOpenStackControlPlaneSpec() + + apiList := map[string]interface{}{ + "foo-1234567890-1234567890-1234567890-1234567890-1234567890": map[string]interface{}{ + "replicas": 1, + }, + } + + glanceTemplate := map[string]interface{}{ + "databaseInstance": "openstack", + "secret": "secret", + "databaseAccount": "account", + "glanceAPIs": apiList, + } + + spec["glance"] = map[string]interface{}{ + "enabled": true, + "uniquePodNames": true, + "template": glanceTemplate, + } + + raw := map[string]interface{}{ + "apiVersion": "core.openstack.org/v1beta1", + "kind": "OpenStackControlPlane", + "metadata": map[string]interface{}{ + "name": "foo", + "namespace": namespace, + }, + "spec": spec, + } + + unstructuredObj := &unstructured.Unstructured{Object: raw} + _, err := controllerutil.CreateOrPatch( + th.Ctx, th.K8sClient, unstructuredObj, func() error { return nil }) + Expect(err).Should(HaveOccurred()) + var statusError *k8s_errors.StatusError + Expect(errors.As(err, &statusError)).To(BeTrue()) + Expect(statusError.ErrStatus.Details.Kind).To(Equal("OpenStackControlPlane")) + Expect(statusError.ErrStatus.Message).To( + ContainSubstring( + "Invalid value: \"foo-1234567890-1234567890-1234567890-1234567890-1234567890\": must be no more than 33 characters"), + ) + }) + + It("Blocks creating ctlplane CRs with wrong glanceapi keys/names", func() { + spec := GetDefaultOpenStackControlPlaneSpec() + + apiList := map[string]interface{}{ + "foo_bar": map[string]interface{}{ + "replicas": 1, + }, + } + + glanceTemplate := map[string]interface{}{ + "databaseInstance": "openstack", + "secret": "secret", + "databaseAccount": "account", + "glanceAPIs": apiList, + } + + spec["glance"] = map[string]interface{}{ + "enabled": true, + "template": glanceTemplate, + } + + raw := map[string]interface{}{ + "apiVersion": "core.openstack.org/v1beta1", + "kind": "OpenStackControlPlane", + "metadata": map[string]interface{}{ + "name": "foo", + "namespace": namespace, + }, + "spec": spec, + } + + unstructuredObj := &unstructured.Unstructured{Object: raw} + _, err := controllerutil.CreateOrPatch( + th.Ctx, th.K8sClient, unstructuredObj, func() error { return nil }) + Expect(err).Should(HaveOccurred()) + var statusError *k8s_errors.StatusError + Expect(errors.As(err, &statusError)).To(BeTrue()) + Expect(statusError.ErrStatus.Details.Kind).To(Equal("OpenStackControlPlane")) + Expect(statusError.ErrStatus.Message).To( + ContainSubstring( + "Invalid value: \"foo_bar\": a lowercase RFC 1123 label must consist"), + ) + }) })