Skip to content

Commit

Permalink
[validation] check glanceAPI names are valid
Browse files Browse the repository at this point in the history
The glanceAPI controller creates StatefulSet for glanceapi to run.
This adds a StatefulSet pod's label
"controller-revision-hash": "<statefulset_name>-<hash>"
to the pod.
The kubernetes label is restricted under 63 char and the revision
hash is an int32, 10 chars + the hyphen. Which results in a default
statefulset max len of 52 chars. The statefulset name also
contain the glance name and the glanceAPI type + 2 hyphens. So the
max len also need to be reduced bye the length of those.

Also the name of the created rabbitmq instance must match a lowercase
RFC 1123.

Depends-On: openstack-k8s-operators/lib-common#532
Depends-On: openstack-k8s-operators/glance-operator#587

Jira: https://issues.redhat.com/browse/OSPRH-8063

Signed-off-by: Martin Schuppert <[email protected]>
  • Loading branch information
stuggi committed Jul 19, 2024
1 parent d662542 commit 819b537
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 11 deletions.
14 changes: 14 additions & 0 deletions apis/core/v1beta1/openstackcontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -974,3 +976,15 @@ func (c CertConfig) GetRenewBeforeHours() string {

return ""
}

// GetGlanceName - returns the glanceName and altGlanceName depending if
// UniquePodNames is configured
func (instance OpenStackControlPlane) GetGlanceName() (string, string) {
glanceName := "glance"
altGlanceName := fmt.Sprintf("glance-%s", instance.UID[:5])
if instance.Spec.Glance.UniquePodNames {
glanceName, altGlanceName = altGlanceName, glanceName
}

return glanceName, altGlanceName
}
16 changes: 16 additions & 0 deletions apis/core/v1beta1/openstackcontrolplane_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad
}

if r.Spec.Glance.Enabled {
glanceName, _ := r.GetGlanceName()
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": "<statefulset_name>-<hash>"
errors = append(errors, err...)
}
errors = append(errors, r.Spec.Glance.Template.ValidateCreate(basePath.Child("glance").Child("template"))...)
}

Expand Down Expand Up @@ -390,6 +398,14 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane
if old.Glance.Template == nil {
old.Glance.Template = &glancev1.GlanceSpecCore{}
}
glanceName, _ := r.GetGlanceName()
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": "<statefulset_name>-<hash>"
errors = append(errors, err...)
}
errors = append(errors, r.Spec.Glance.Template.ValidateUpdate(*old.Glance.Template, basePath.Child("glance").Child("template"))...)
}

Expand Down
2 changes: 1 addition & 1 deletion apis/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions apis/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
6 changes: 1 addition & 5 deletions pkg/openstack/glance.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.GetGlanceName()
// Ensure the alternate cinder CR doesn't exist, as the ramdomPodNames flag may have been toggled
glance := &glancev1.Glance{
ObjectMeta: metav1.ObjectMeta{
Expand Down
134 changes: 134 additions & 0 deletions tests/functional/ctlplane/openstackoperator_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
)
})
})

0 comments on commit 819b537

Please sign in to comment.