Skip to content

Add support for advanced.config #221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/v1beta1/rabbitmqcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ type RabbitmqClusterConfigurationSpec struct {
// Modify to add to the rabbitmq.conf file in addition to default configurations set by the operator. Modify this property on an existing RabbitmqCluster will trigger a StatefulSet rolling restart and will cause rabbitmq downtime.
// +kubebuilder:validation:MaxLength:=2000
AdditionalConfig string `json:"additionalConfig,omitempty"`
// Specify any rabbitmq advanced.config configurations
// +kubebuilder:validation:MaxLength:=100000
AdvancedConfig string `json:"advancedConfig,omitempty"`
}

// The settings for the persistent storage desired for each Pod in the RabbitmqCluster.
Expand Down
35 changes: 26 additions & 9 deletions config/crd/bases/rabbitmq.com_rabbitmqclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,10 @@ spec:
description: RabbitmqCluster is the Schema for the rabbitmqclusters API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
Expand Down Expand Up @@ -635,7 +631,7 @@ spec:
clientService:
properties:
metadata:
description: It is used in ClientService, and StatefulSet
description: It is used in ClientService and StatefulSet
properties:
annotations:
additionalProperties:
Expand Down Expand Up @@ -762,6 +758,23 @@ spec:
description: 'Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels'
type: object
type: object
type: object
statefulSet:
properties:
metadata:
description: It is used in ClientService and StatefulSet
properties:
annotations:
additionalProperties:
type: string
description: 'Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations'
type: object
labels:
additionalProperties:
type: string
description: 'Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels'
type: object
type: object
spec:
description: Spec defines the desired identities of pods in this set.
properties:
Expand Down Expand Up @@ -809,7 +822,7 @@ spec:
description: template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet.
properties:
metadata:
description: EmbeddedObjectMeta contains a subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta Only fields which are relevant to embedded resources are included. It is used in StatefulSet, PersistentVolumeClaim, and PodTemplate
description: EmbeddedObjectMeta contains a subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta Only fields which are relevant to embedded resources are included. It is used in PersistentVolumeClaim and PodTemplate
properties:
annotations:
additionalProperties:
Expand Down Expand Up @@ -4432,7 +4445,7 @@ spec:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
description: EmbeddedObjectMeta contains a subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta Only fields which are relevant to embedded resources are included. It is used in StatefulSet, PersistentVolumeClaim, and PodTemplate
description: EmbeddedObjectMeta contains a subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta Only fields which are relevant to embedded resources are included. It is used in PersistentVolumeClaim and PodTemplate
properties:
annotations:
additionalProperties:
Expand Down Expand Up @@ -4581,6 +4594,10 @@ spec:
type: string
maxItems: 100
type: array
advancedConfig:
description: Specify any rabbitmq advanced.config configurations
maxLength: 100000
type: string
type: object
replicas:
description: Replicas is the number of nodes in the RabbitMQ cluster.
Expand Down
3 changes: 3 additions & 0 deletions internal/resource/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ func (builder *ServerConfigMapBuilder) Update(object runtime.Object) error {
}
}

if builder.Instance.Spec.Rabbitmq.AdvancedConfig != "" {
configMap.Data["advanced.config"] = builder.Instance.Spec.Rabbitmq.AdvancedConfig
}
configMap.Data["rabbitmq.conf"] = rmqConfBuilder.String()
return nil
}
Expand Down
22 changes: 17 additions & 5 deletions internal/resource/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ var _ = Describe("GenerateServerConfigMap", func() {
"rabbitmq_management]."

plugins, ok := configMap.Data["enabled_plugins"]
Expect(ok).To(BeTrue())
Expect(ok).To(BeTrue(), "key 'enabled_plugins' should be present")
Expect(plugins).To(Equal(expectedEnabledPlugins))
})

Expand Down Expand Up @@ -120,7 +120,7 @@ cluster_name = ` + builder.Instance.Name + "\n"

Expect(configMapBuilder.Update(configMap)).To(Succeed())
rabbitmqConf, ok := configMap.Data["rabbitmq.conf"]
Expect(ok).To(BeTrue())
Expect(ok).To(BeTrue(), "key 'rabbitmq.conf' should be present")
Expect(rabbitmqConf).To(Equal(defaultRabbitmqConf))
})

Expand All @@ -143,10 +143,22 @@ my-config-property-1 = better-value`

Expect(configMapBuilder.Update(configMap)).To(Succeed())
rabbitmqConf, ok := configMap.Data["rabbitmq.conf"]
Expect(ok).To(BeTrue())
Expect(ok).To(BeTrue(), "key 'rabbitmq.conf' should be present")
Expect(rabbitmqConf).To(Equal(expectedRabbitmqConf))
})

It("sets data.advancedConfig when provided", func() {
instance.Spec.Rabbitmq.AdvancedConfig = `
[
{rabbit, [{auth_backends, [rabbit_auth_backend_ldap]}]}
].`
Expect(configMapBuilder.Update(configMap)).To(Succeed())
advancedConfig, ok := configMap.Data["advanced.config"]
Expect(ok).To(BeTrue(), "key 'advanced.config' should be present")
Expect(advancedConfig).To(Equal("\n[\n {rabbit, [{auth_backends, [rabbit_auth_backend_ldap]}]}\n]."))

})

Context("TLS", func() {
It("adds TLS config when TLS is enabled", func() {
instance = rabbitmqv1beta1.RabbitmqCluster{
Expand All @@ -162,7 +174,7 @@ my-config-property-1 = better-value`

Expect(configMapBuilder.Update(configMap)).To(Succeed())
rabbitmqConf, ok := configMap.Data["rabbitmq.conf"]
Expect(ok).To(BeTrue())
Expect(ok).To(BeTrue(), "key 'rabbitmq.conf' should be present")
Expect(rabbitmqConf).To(ContainSubstring(`
ssl_options.certfile=/etc/rabbitmq-tls/tls.crt
ssl_options.keyfile=/etc/rabbitmq-tls/tls.key
Expand All @@ -187,7 +199,7 @@ listeners.ssl.default=5671

Expect(configMapBuilder.Update(configMap)).To(Succeed())
rabbitmqConf, ok := configMap.Data["rabbitmq.conf"]
Expect(ok).To(BeTrue())
Expect(ok).To(BeTrue(), "key 'rabbitmq.conf' should be present")
Expect(rabbitmqConf).To(ContainSubstring(`
ssl_options.certfile=/etc/rabbitmq-tls/tls.crt
ssl_options.keyfile=/etc/rabbitmq-tls/tls.key
Expand Down
1 change: 1 addition & 0 deletions internal/resource/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ func (builder *StatefulSetBuilder) podTemplateSpec(annotations, labels map[strin
Image: builder.Instance.Spec.Image,
Command: []string{
"sh", "-c", "cp /tmp/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf && echo '' >> /etc/rabbitmq/rabbitmq.conf ; " +
"cp /tmp/rabbitmq/advanced.config /etc/rabbitmq/advanced.config ; " +
"cp /tmp/erlang-cookie-secret/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie " +
"&& chown 999:999 /var/lib/rabbitmq/.erlang.cookie " +
"&& chmod 600 /var/lib/rabbitmq/.erlang.cookie ; " +
Expand Down
1 change: 1 addition & 0 deletions internal/resource/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,7 @@ var _ = Describe("StatefulSet", func() {
container := extractContainer(initContainers, "copy-config")
Expect(container.Command).To(Equal([]string{
"sh", "-c", "cp /tmp/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf && echo '' >> /etc/rabbitmq/rabbitmq.conf ; " +
"cp /tmp/rabbitmq/advanced.config /etc/rabbitmq/advanced.config ; " +
"cp /tmp/erlang-cookie-secret/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie " +
"&& chown 999:999 /var/lib/rabbitmq/.erlang.cookie " +
"&& chmod 600 /var/lib/rabbitmq/.erlang.cookie ; " +
Expand Down
19 changes: 19 additions & 0 deletions system_tests/system_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,25 @@ cluster_keepalive_interval = 10000`
Expect(string(output)).Should(ContainSubstring("cluster_keepalive_interval = 10000"))
Expect(string(output)).Should(ContainSubstring("cluster_partition_handling = ignore"))
})

By("updating the advanced.config file when advancedConfig are modifed", func() {
Expect(updateRabbitmqCluster(rmqClusterClient, cluster.Name, cluster.Namespace, func(cluster *rabbitmqv1beta1.RabbitmqCluster) {
cluster.Spec.Rabbitmq.AdvancedConfig = `[
{rabbit, [{auth_backends, [rabbit_auth_backend_ldap]}]}
].`
})).To(Succeed())

// wait for statefulSet to be restarted
waitForRabbitmqUpdate(cluster)

output, err := kubectlExec(namespace,
statefulSetPodName(cluster, 0),
"cat",
"/etc/rabbitmq/advanced.config",
)
Expect(err).NotTo(HaveOccurred())
Expect(string(output)).Should(ContainSubstring("[\n {rabbit, [{auth_backends, [rabbit_auth_backend_ldap]}]}\n]."))
})
})
})

Expand Down