From 64c9d2703d5436788b7817f3c5e150cf681f5c34 Mon Sep 17 00:00:00 2001 From: cuisongliu Date: Wed, 2 Oct 2024 23:03:22 +0800 Subject: [PATCH] feat(main): add webhook test (#23) * feat(main): add webhook test default Signed-off-by: cuisongliu * feat(main): add webhook test default Signed-off-by: cuisongliu * feat(main): add webhook test validate Signed-off-by: cuisongliu --------- Signed-off-by: cuisongliu --- api/v1beta1/automq_types.go | 2 - api/v1beta1/automq_webhook.go | 45 ++++++++++-- api/v1beta1/webhook_suite_test.go | 113 ++++++++++++++++++++++++++++-- 3 files changed, 149 insertions(+), 11 deletions(-) diff --git a/api/v1beta1/automq_types.go b/api/v1beta1/automq_types.go index f5dbdd9..eb3fec8 100644 --- a/api/v1beta1/automq_types.go +++ b/api/v1beta1/automq_types.go @@ -134,10 +134,8 @@ type AutoMQSpec struct { S3 S3Spec `json:"s3,omitempty"` // ClusterID is the ID of the cluster. Default is "rZdE0DjZSrqy96PXrMUZVw" // +kubebuilder:validation:Required - // +kubebuilder:validation:default=rZdE0DjZSrqy96PXrMUZVw ClusterID string `json:"clusterID,omitempty"` // Image is the image of the AutoMQ - // +kubebuilder:validation:default=automqinc/automq:1.2.0-rc1 Image string `json:"image,omitempty"` // Metrics is the metrics configuration for the AutoMQ Metrics MetricsSpec `json:"metrics,omitempty"` diff --git a/api/v1beta1/automq_webhook.go b/api/v1beta1/automq_webhook.go index 2355c3d..dd97fb0 100644 --- a/api/v1beta1/automq_webhook.go +++ b/api/v1beta1/automq_webhook.go @@ -17,6 +17,7 @@ limitations under the License. package v1beta1 import ( + "fmt" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -50,7 +51,7 @@ func (r *AutoMQ) Default() { r.Spec.ClusterID = "rZdE0DjZSrqy96PXrMUZVw" } if r.Spec.S3.Bucket == "" { - r.Spec.S3.Bucket = "automq" + r.Spec.S3.Bucket = "ko3" } if r.Spec.Controller.JVMOptions == nil { r.Spec.Controller.JVMOptions = []string{"-Xms1g", "-Xmx1g", "-XX:MetaspaceSize=96m"} @@ -74,16 +75,32 @@ var _ webhook.Validator = &AutoMQ{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type func (r *AutoMQ) ValidateCreate() (admission.Warnings, error) { automqlog.Info("validate create", "name", r.Name) - - // TODO(user): fill in your validation logic upon object creation. + if err := validate(r); err != nil { + return nil, err + } return nil, nil } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type func (r *AutoMQ) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { automqlog.Info("validate update", "name", r.Name) + mqOld := old.(*AutoMQ) - // TODO(user): fill in your validation logic upon object update. + if r.Spec.S3.Endpoint != mqOld.Spec.S3.Endpoint { + return nil, fmt.Errorf("field s3.Endpoint is immutable") + } + if r.Spec.S3.Region != mqOld.Spec.S3.Region { + return nil, fmt.Errorf("field s3.Region is immutable") + } + if r.Spec.S3.Bucket != mqOld.Spec.S3.Bucket { + return nil, fmt.Errorf("field s3.Bucket is immutable") + } + if r.Spec.ClusterID != mqOld.Spec.ClusterID { + return nil, fmt.Errorf("field clusterID is immutable") + } + if err := validate(r); err != nil { + return nil, err + } return nil, nil } @@ -94,3 +111,23 @@ func (r *AutoMQ) ValidateDelete() (admission.Warnings, error) { // TODO(user): fill in your validation logic upon object deletion. return nil, nil } + +func validate(r *AutoMQ) error { + if r.Spec.S3.Endpoint == "" { + return fmt.Errorf("field s3.Endpoint is required") + } + if r.Spec.S3.Region == "" { + return fmt.Errorf("field s3.Region is required") + } + if r.Spec.S3.Bucket == "" { + return fmt.Errorf("field s3.Bucket is required") + } + if r.Spec.ClusterID == "" { + return fmt.Errorf("field clusterID is required") + } + if r.Spec.Image == "" { + return fmt.Errorf("field image is required") + } + + return nil +} diff --git a/api/v1beta1/webhook_suite_test.go b/api/v1beta1/webhook_suite_test.go index a89e1b3..eeb454c 100644 --- a/api/v1beta1/webhook_suite_test.go +++ b/api/v1beta1/webhook_suite_test.go @@ -20,6 +20,7 @@ import ( "context" "crypto/tls" "fmt" + "k8s.io/apimachinery/pkg/api/errors" "net" "path/filepath" "runtime" @@ -77,12 +78,114 @@ func initAutoMQ() *AutoMQ { } var _ = Describe("Default", func() { - It("ImageName", func() { - aq := initAutoMQ() - err := k8sClient.Create(context.Background(), aq) - Expect(err).To(BeNil()) - Expect(aq.Spec.Image).To(Equal(DefaultImageName)) + Context("Default Webhook", func() { + BeforeEach(func() { + aq := initAutoMQ() + _ = k8sClient.Delete(context.Background(), aq) + }) + It("Default ImageName", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(aq), aq) + Expect(err).To(BeNil()) + Expect(aq.Spec.Image).To(Equal(DefaultImageName)) + }) + It("Default Region", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(aq), aq) + Expect(err).To(BeNil()) + Expect(aq.Spec.S3.Region).To(Equal("us-east-1")) + }) + It("Default ClusterID", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(aq), aq) + Expect(err).To(BeNil()) + Expect(aq.Spec.ClusterID).To(Equal("rZdE0DjZSrqy96PXrMUZVw")) + err = k8sClient.Delete(context.Background(), aq) + Expect(err).To(BeNil()) + }) + It("Default Bucket", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(aq), aq) + Expect(err).To(BeNil()) + Expect(aq.Spec.S3.Bucket).To(Equal("ko3")) + }) + It("Default Replicas", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(aq), aq) + Expect(err).To(BeNil()) + Expect(aq.Spec.Controller.Replicas).To(Equal(int32(1))) + Expect(aq.Spec.Broker.Replicas).To(Equal(int32(1))) + }) + It("Default JVM", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(aq), aq) + Expect(err).To(BeNil()) + Expect(aq.Spec.Controller.JVMOptions).To(Equal([]string{"-Xms1g", "-Xmx1g", "-XX:MetaspaceSize=96m"})) + Expect(aq.Spec.Broker.JVMOptions).To(Equal([]string{"-Xms1g", "-Xmx1g", "-XX:MetaspaceSize=96m", "-XX:MaxDirectMemorySize=1G"})) + }) }) + +}) +var _ = Describe("Update", func() { + Context("Update Webhook", func() { + BeforeEach(func() { + aq := initAutoMQ() + _ = k8sClient.Delete(context.Background(), aq) + }) + It("Update Endpoint", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + aq.Spec.S3.Endpoint = "http://localhost:9001" + err = k8sClient.Update(context.Background(), aq) + Expect(true).To(Equal(errors.IsForbidden(err))) + Expect(err.Error()).To(ContainSubstring("s3.Endpoint")) + Expect(err.Error()).To(ContainSubstring("immutable")) + }) + It("Update Region", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + aq.Spec.S3.Region = "minioadmin1" + err = k8sClient.Update(context.Background(), aq) + Expect(true).To(Equal(errors.IsForbidden(err))) + Expect(err.Error()).To(ContainSubstring("s3.Region")) + Expect(err.Error()).To(ContainSubstring("immutable")) + }) + It("Update Bucket", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + aq.Spec.S3.Bucket = "minioadmin1" + err = k8sClient.Update(context.Background(), aq) + Expect(true).To(Equal(errors.IsForbidden(err))) + Expect(err.Error()).To(ContainSubstring("s3.Bucket")) + Expect(err.Error()).To(ContainSubstring("immutable")) + }) + It("Update ClusterID", func() { + aq := initAutoMQ() + err := k8sClient.Create(context.Background(), aq) + Expect(err).To(BeNil()) + aq.Spec.ClusterID = "minioadmin1" + err = k8sClient.Update(context.Background(), aq) + Expect(true).To(Equal(errors.IsForbidden(err))) + Expect(err.Error()).To(ContainSubstring("clusterID")) + Expect(err.Error()).To(ContainSubstring("immutable")) + }) + }) + }) var _ = BeforeSuite(func() {