Skip to content

Commit

Permalink
[validation] check rabbitmq instance names are valid
Browse files Browse the repository at this point in the history
The rabbitmq controller creates StatefulSet for rabbitmq 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. With this the max name
must not exceed 52 chars.

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

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

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

Signed-off-by: Martin Schuppert <[email protected]>
  • Loading branch information
stuggi committed Jul 17, 2024
1 parent 0eb4c80 commit 4496dc1
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 2 deletions.
24 changes: 22 additions & 2 deletions apis/core/v1beta1/openstackcontrolplane_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,23 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad
if r.Spec.Memcached.Enabled {
if r.Spec.Memcached.Templates != nil {
err := common_webhook.ValidateDNS1123Label(
basePath.Child("memcached").Child("template"),
basePath.Child("memcached").Child("templates"),
maps.Keys(*r.Spec.Memcached.Templates),
memcachedv1.CrMaxLengthCorrection) // omit issue with statefulset pod label "controller-revision-hash": "<statefulset_name>-<hash>"
errors = append(errors, err...)
}
}

if r.Spec.Rabbitmq.Enabled {
if r.Spec.Rabbitmq.Templates != nil {
err := common_webhook.ValidateDNS1123Label(
basePath.Child("rabbitmq").Child("templates"),
maps.Keys(*r.Spec.Rabbitmq.Templates),
memcachedv1.CrMaxLengthCorrection) // omit issue with statefulset pod label "controller-revision-hash": "<statefulset_name>-<hash>"
errors = append(errors, err...)
}
}

return warnings, errors
}

Expand Down Expand Up @@ -428,13 +438,23 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane
if r.Spec.Memcached.Enabled {
if r.Spec.Memcached.Templates != nil {
err := common_webhook.ValidateDNS1123Label(
basePath.Child("memcached").Child("template"),
basePath.Child("memcached").Child("templates"),
maps.Keys(*r.Spec.Memcached.Templates),
memcachedv1.CrMaxLengthCorrection) // omit issue with statefulset pod label "controller-revision-hash": "<statefulset_name>-<hash>"
errors = append(errors, err...)
}
}

if r.Spec.Rabbitmq.Enabled {
if r.Spec.Rabbitmq.Templates != nil {
err := common_webhook.ValidateDNS1123Label(
basePath.Child("rabbitmq").Child("templates"),
maps.Keys(*r.Spec.Rabbitmq.Templates),
memcachedv1.CrMaxLengthCorrection) // omit issue with statefulset pod label "controller-revision-hash": "<statefulset_name>-<hash>"
errors = append(errors, err...)
}
}

return errors
}

Expand Down
74 changes: 74 additions & 0 deletions tests/functional/ctlplane/openstackoperator_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1937,4 +1937,78 @@ var _ = Describe("OpenStackOperator Webhook", func() {
"Invalid value: \"foo_bar\": a lowercase RFC 1123 label must consist"),
)
})

It("Blocks creating ctlplane CRs with to long rabbitmq keys/names", func() {
spec := GetDefaultOpenStackControlPlaneSpec()

rabbitmqTemplate := map[string]interface{}{
"foo-1234567890-1234567890-1234567890-1234567890-1234567890": map[string]interface{}{
"replicas": 1,
},
}

spec["rabbitmq"] = map[string]interface{}{
"enabled": true,
"templates": rabbitmqTemplate,
}

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 52 characters"),
)
})

It("Blocks creating ctlplane CRs with wrong rabbitmq keys/names", func() {
spec := GetDefaultOpenStackControlPlaneSpec()

rabbitmqTemplate := map[string]interface{}{
"foo_bar": map[string]interface{}{
"replicas": 1,
},
}

spec["rabbitmq"] = map[string]interface{}{
"enabled": true,
"templates": rabbitmqTemplate,
}

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 4496dc1

Please sign in to comment.