Skip to content

Commit 65bc9ed

Browse files
authored
Merge pull request #113 from rabbitmq/schema-sync-parameter
Support for setting schema replication parameters
2 parents 17614f8 + c1e913d commit 65bc9ed

28 files changed

+1423
-19
lines changed

PROJECT

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ resources:
2222
- group: rabbitmq.com
2323
kind: Permission
2424
version: v1alpha2
25+
- group: rabbitmq.com
26+
kind: SchemaReplication
27+
version: v1alpha2
2528
version: "2"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
RabbitMQ Messaging Topology Kubernetes Operator
3+
Copyright 2021 VMware, Inc.
4+
5+
This product is licensed to you under the Mozilla Public License 2.0 license (the "License"). You may not use this product except in compliance with the Mozilla 2.0 License.
6+
7+
This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8+
*/
9+
10+
package v1alpha2
11+
12+
import (
13+
corev1 "k8s.io/api/core/v1"
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+
"k8s.io/apimachinery/pkg/runtime/schema"
16+
)
17+
18+
// SchemaReplicationSpec defines the desired state of SchemaReplication
19+
type SchemaReplicationSpec struct {
20+
// Reference to the RabbitmqCluster that schema replication would be set for. Must be an existing cluster.
21+
// +kubebuilder:validation:Required
22+
RabbitmqClusterReference RabbitmqClusterReference `json:"rabbitmqClusterReference"`
23+
// Defines a Secret which contains credentials to be used for schema replication.
24+
// The Secret must contain the keys `endpoints`, `username` and `password` in its Data field, or operator will error.
25+
// `endpoints` should be one or multiple endpoints separated by ','.
26+
// +kubebuilder:validation:Required
27+
UpstreamSecret *corev1.LocalObjectReference `json:"upstreamSecret,omitempty"`
28+
}
29+
30+
// SchemaReplicationStatus defines the observed state of SchemaReplication
31+
type SchemaReplicationStatus struct {
32+
// observedGeneration is the most recent successful generation observed for this Queue. It corresponds to the
33+
// Queue's generation, which is updated on mutation by the API Server.
34+
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
35+
Conditions []Condition `json:"conditions,omitempty"`
36+
}
37+
38+
// +kubebuilder:object:root=true
39+
// +kubebuilder:subresource:status
40+
41+
// SchemaReplication is the Schema for the schemareplications API
42+
// This feature requires Tanzu RabbitMQ with schema replication plugin.
43+
// For more information, see: https://tanzu.vmware.com/rabbitmq and https://www.rabbitmq.com/definitions-standby.html.
44+
type SchemaReplication struct {
45+
metav1.TypeMeta `json:",inline"`
46+
metav1.ObjectMeta `json:"metadata,omitempty"`
47+
48+
Spec SchemaReplicationSpec `json:"spec,omitempty"`
49+
Status SchemaReplicationStatus `json:"status,omitempty"`
50+
}
51+
52+
// +kubebuilder:object:root=true
53+
54+
// SchemaReplicationList contains a list of SchemaReplication
55+
type SchemaReplicationList struct {
56+
metav1.TypeMeta `json:",inline"`
57+
metav1.ListMeta `json:"metadata,omitempty"`
58+
Items []SchemaReplication `json:"items"`
59+
}
60+
61+
func init() {
62+
SchemeBuilder.Register(&SchemaReplication{}, &SchemaReplicationList{})
63+
}
64+
65+
func (s *SchemaReplication) GroupResource() schema.GroupResource {
66+
return schema.GroupResource{
67+
Group: s.GroupVersionKind().Group,
68+
Resource: s.GroupVersionKind().Kind,
69+
}
70+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package v1alpha2
2+
3+
import (
4+
"context"
5+
. "github.com/onsi/ginkgo"
6+
. "github.com/onsi/gomega"
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"k8s.io/apimachinery/pkg/types"
10+
)
11+
12+
var _ = Describe("schemaReplication spec", func() {
13+
It("creates a schemaReplication", func() {
14+
replication := SchemaReplication{
15+
ObjectMeta: metav1.ObjectMeta{
16+
Name: "replication",
17+
Namespace: "default",
18+
},
19+
Spec: SchemaReplicationSpec{
20+
RabbitmqClusterReference: RabbitmqClusterReference{
21+
Name: "some-cluster",
22+
},
23+
UpstreamSecret: &corev1.LocalObjectReference{
24+
Name: "a-secret",
25+
},
26+
}}
27+
Expect(k8sClient.Create(context.Background(), &replication)).To(Succeed())
28+
29+
fetched := &SchemaReplication{}
30+
Expect(k8sClient.Get(context.Background(), types.NamespacedName{
31+
Name: replication.Name,
32+
Namespace: replication.Namespace,
33+
}, fetched)).To(Succeed())
34+
Expect(fetched.Spec.RabbitmqClusterReference).To(Equal(RabbitmqClusterReference{
35+
Name: "some-cluster",
36+
}))
37+
Expect(fetched.Spec.UpstreamSecret.Name).To(Equal("a-secret"))
38+
})
39+
})
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package v1alpha2
2+
3+
import (
4+
"fmt"
5+
apierrors "k8s.io/apimachinery/pkg/api/errors"
6+
"k8s.io/apimachinery/pkg/runtime"
7+
"k8s.io/apimachinery/pkg/util/validation/field"
8+
ctrl "sigs.k8s.io/controller-runtime"
9+
"sigs.k8s.io/controller-runtime/pkg/webhook"
10+
)
11+
12+
func (s *SchemaReplication) SetupWebhookWithManager(mgr ctrl.Manager) error {
13+
return ctrl.NewWebhookManagedBy(mgr).
14+
For(s).
15+
Complete()
16+
}
17+
18+
// +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1alpha2-schemareplication,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=schemareplications,versions=v1alpha2,name=vschemareplication.kb.io,sideEffects=none,admissionReviewVersions=v1
19+
20+
var _ webhook.Validator = &SchemaReplication{}
21+
22+
// no validation on create
23+
func (s *SchemaReplication) ValidateCreate() error {
24+
return nil
25+
}
26+
27+
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
28+
func (s *SchemaReplication) ValidateUpdate(old runtime.Object) error {
29+
oldReplication, ok := old.(*SchemaReplication)
30+
if !ok {
31+
return apierrors.NewBadRequest(fmt.Sprintf("expected a schema replication type but got a %T", old))
32+
}
33+
34+
if s.Spec.RabbitmqClusterReference != oldReplication.Spec.RabbitmqClusterReference {
35+
return apierrors.NewForbidden(s.GroupResource(), s.Name,
36+
field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), "update on rabbitmqClusterReference is forbidden"))
37+
}
38+
return nil
39+
}
40+
41+
// no validation on delete
42+
func (s *SchemaReplication) ValidateDelete() error {
43+
return nil
44+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package v1alpha2
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/gomega"
6+
corev1 "k8s.io/api/core/v1"
7+
apierrors "k8s.io/apimachinery/pkg/api/errors"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
)
10+
11+
var _ = Describe("schema-replication webhook", func() {
12+
var replication = SchemaReplication{
13+
ObjectMeta: metav1.ObjectMeta{
14+
Name: "test-replication",
15+
},
16+
Spec: SchemaReplicationSpec{
17+
UpstreamSecret: &corev1.LocalObjectReference{
18+
Name: "a-secret",
19+
},
20+
RabbitmqClusterReference: RabbitmqClusterReference{
21+
Name: "a-cluster",
22+
},
23+
},
24+
}
25+
26+
It("does not allow updates on RabbitmqClusterReference", func() {
27+
updated := replication.DeepCopy()
28+
updated.Spec.RabbitmqClusterReference = RabbitmqClusterReference{
29+
Name: "different-cluster",
30+
}
31+
Expect(apierrors.IsForbidden(updated.ValidateUpdate(&replication))).To(BeTrue())
32+
})
33+
34+
It("allows updates on spec.upstreamSecret", func() {
35+
updated := replication.DeepCopy()
36+
updated.Spec.UpstreamSecret = &corev1.LocalObjectReference{
37+
Name: "a-different-secret",
38+
}
39+
Expect(updated.ValidateUpdate(&replication)).To(Succeed())
40+
})
41+
})

api/v1alpha2/zz_generated.deepcopy.go

Lines changed: 102 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)