From 84555b27db7376941568bbcadfca7457e2e4d234 Mon Sep 17 00:00:00 2001 From: liyang Date: Mon, 16 Dec 2024 23:57:21 +0800 Subject: [PATCH 1/6] feat: initialize admission webhook --- PROJECT | 14 +- apis/v1alpha1/greptimedbcluster_webhook.go | 63 ++++++++ apis/v1alpha1/greptimedbstandalone_webhook.go | 63 ++++++++ config/certmanager/certificate.yaml | 39 +++++ config/certmanager/kustomization.yaml | 5 + config/certmanager/kustomizeconfig.yaml | 16 ++ config/default/manager_webhook_patch.yaml | 23 +++ config/default/webhookcainjection_patch.yaml | 29 ++++ config/webhook/kustomization.yaml | 6 + config/webhook/kustomizeconfig.yaml | 25 ++++ config/webhook/service.yaml | 20 +++ tests/e2e/webhook_suite_test.go | 141 ++++++++++++++++++ 12 files changed, 442 insertions(+), 2 deletions(-) create mode 100644 apis/v1alpha1/greptimedbcluster_webhook.go create mode 100644 apis/v1alpha1/greptimedbstandalone_webhook.go create mode 100644 config/certmanager/certificate.yaml create mode 100644 config/certmanager/kustomization.yaml create mode 100644 config/certmanager/kustomizeconfig.yaml create mode 100644 config/default/manager_webhook_patch.yaml create mode 100644 config/default/webhookcainjection_patch.yaml create mode 100644 config/webhook/kustomization.yaml create mode 100644 config/webhook/kustomizeconfig.yaml create mode 100644 config/webhook/service.yaml create mode 100644 tests/e2e/webhook_suite_test.go diff --git a/PROJECT b/PROJECT index 95068389..8c7fb638 100644 --- a/PROJECT +++ b/PROJECT @@ -1,3 +1,7 @@ +# Code generated by tool. DO NOT EDIT. +# This file is used to track the info used to scaffold your project +# and allow the plugins properly work. +# More info: https://book.kubebuilder.io/reference/project-config.html domain: greptime.io layout: - go.kubebuilder.io/v3 @@ -10,14 +14,20 @@ resources: controller: true domain: greptime.io kind: GreptimeDBCluster - path: github.com/GreptimeTeam/greptimedb-operator/apis/v1alpha1 + path: github.com/GreptimeTeam/greptimedb-operator/api/v1alpha1 version: v1alpha1 + webhooks: + validation: true + webhookVersion: v1 - api: crdVersion: v1 namespaced: true controller: true domain: greptime.io kind: GreptimeDBStandalone - path: github.com/greptime/greptimedb-operator/apis/v1alpha1 + path: github.com/GreptimeTeam/greptimedb-operator/api/v1alpha1 version: v1alpha1 + webhooks: + validation: true + webhookVersion: v1 version: "3" diff --git a/apis/v1alpha1/greptimedbcluster_webhook.go b/apis/v1alpha1/greptimedbcluster_webhook.go new file mode 100644 index 00000000..ff0119b3 --- /dev/null +++ b/apis/v1alpha1/greptimedbcluster_webhook.go @@ -0,0 +1,63 @@ +// Copyright 2024 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var greptimedbclusterlog = logf.Log.WithName("greptimedbcluster-resource") + +func (r *GreptimeDBCluster) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-greptime-io-v1alpha1-greptimedbcluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=greptime.io,resources=greptimedbclusters,verbs=create;update,versions=v1alpha1,name=vgreptimedbcluster.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &GreptimeDBCluster{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *GreptimeDBCluster) ValidateCreate() (admission.Warnings, error) { + greptimedbclusterlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *GreptimeDBCluster) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + greptimedbclusterlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *GreptimeDBCluster) ValidateDelete() (admission.Warnings, error) { + greptimedbclusterlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/apis/v1alpha1/greptimedbstandalone_webhook.go b/apis/v1alpha1/greptimedbstandalone_webhook.go new file mode 100644 index 00000000..836d72c6 --- /dev/null +++ b/apis/v1alpha1/greptimedbstandalone_webhook.go @@ -0,0 +1,63 @@ +// Copyright 2024 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var greptimedbstandalonelog = logf.Log.WithName("greptimedbstandalone-resource") + +func (r *GreptimeDBStandalone) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-greptime-io-v1alpha1-greptimedbstandalone,mutating=false,failurePolicy=fail,sideEffects=None,groups=greptime.io,resources=greptimedbstandalones,verbs=create;update,versions=v1alpha1,name=vgreptimedbstandalone.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &GreptimeDBStandalone{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *GreptimeDBStandalone) ValidateCreate() (admission.Warnings, error) { + greptimedbstandalonelog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *GreptimeDBStandalone) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + greptimedbstandalonelog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *GreptimeDBStandalone) ValidateDelete() (admission.Warnings, error) { + greptimedbstandalonelog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml new file mode 100644 index 00000000..be656206 --- /dev/null +++ b/config/certmanager/certificate.yaml @@ -0,0 +1,39 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/name: issuer + app.kubernetes.io/instance: selfsigned-issuer + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: greptimedb-operator + app.kubernetes.io/part-of: greptimedb-operator + app.kubernetes.io/managed-by: kustomize + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: serving-cert + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: greptimedb-operator + app.kubernetes.io/part-of: greptimedb-operator + app.kubernetes.io/managed-by: kustomize + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + dnsNames: + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml new file mode 100644 index 00000000..bebea5a5 --- /dev/null +++ b/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000..e631f777 --- /dev/null +++ b/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000..738de350 --- /dev/null +++ b/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000..466ed14b --- /dev/null +++ b/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,29 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: mutatingwebhookconfiguration + app.kubernetes.io/instance: mutating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: greptimedb-operator + app.kubernetes.io/part-of: greptimedb-operator + app.kubernetes.io/managed-by: kustomize + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: validatingwebhookconfiguration + app.kubernetes.io/instance: validating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: greptimedb-operator + app.kubernetes.io/part-of: greptimedb-operator + app.kubernetes.io/managed-by: kustomize + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml new file mode 100644 index 00000000..9cf26134 --- /dev/null +++ b/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000..25e21e3c --- /dev/null +++ b/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml new file mode 100644 index 00000000..bf199fd5 --- /dev/null +++ b/config/webhook/service.yaml @@ -0,0 +1,20 @@ + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: service + app.kubernetes.io/instance: webhook-service + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: greptimedb-operator + app.kubernetes.io/part-of: greptimedb-operator + app.kubernetes.io/managed-by: kustomize + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/tests/e2e/webhook_suite_test.go b/tests/e2e/webhook_suite_test.go new file mode 100644 index 00000000..7ff6281a --- /dev/null +++ b/tests/e2e/webhook_suite_test.go @@ -0,0 +1,141 @@ +// Copyright 2022 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package e2e + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + "github.com/GreptimeTeam/greptimedb-operator/apis/v1alpha1" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "resources")}, + ErrorIfCRDPathMissing: false, + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := runtime.NewScheme() + err = v1alpha1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + LeaderElection: false, + Metrics: metricsserver.Options{ + BindAddress: "0", + }, + WebhookServer: webhook.NewServer(webhook.Options{ + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + }), + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&v1alpha1.GreptimeDBCluster{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + err = (&v1alpha1.GreptimeDBStandalone{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + conn.Close() + return nil + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) From 7282fc4e5dc4e42bf7fb11a6769b8e1c920d87b7 Mon Sep 17 00:00:00 2001 From: liyang Date: Tue, 17 Dec 2024 00:00:44 +0800 Subject: [PATCH 2/6] refactor: generate code --- apis/v1alpha1/zz_generated.deepcopy.go | 2 +- config/webhook/manifests.yaml | 46 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 config/webhook/manifests.yaml diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index f61e5608..54e50504 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -21,7 +21,7 @@ package v1alpha1 import ( appsv1 "k8s.io/api/apps/v1" "k8s.io/api/core/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml new file mode 100644 index 00000000..759eb57b --- /dev/null +++ b/config/webhook/manifests.yaml @@ -0,0 +1,46 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-greptime-io-v1alpha1-greptimedbcluster + failurePolicy: Fail + name: vgreptimedbcluster.kb.io + rules: + - apiGroups: + - greptime.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - greptimedbclusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-greptime-io-v1alpha1-greptimedbstandalone + failurePolicy: Fail + name: vgreptimedbstandalone.kb.io + rules: + - apiGroups: + - greptime.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - greptimedbstandalones + sideEffects: None From 3b33caaa0f3a81d10e8337d343d9560bb297edbe Mon Sep 17 00:00:00 2001 From: liyang Date: Tue, 17 Dec 2024 00:17:48 +0800 Subject: [PATCH 3/6] feat: add license header --- config/certmanager/certificate.yaml | 14 ++ config/certmanager/kustomization.yaml | 14 ++ config/certmanager/kustomizeconfig.yaml | 14 ++ config/default/manager_webhook_patch.yaml | 14 ++ config/default/webhookcainjection_patch.yaml | 14 ++ config/webhook/kustomization.yaml | 14 ++ config/webhook/kustomizeconfig.yaml | 14 ++ config/webhook/manifests.yaml | 14 ++ config/webhook/service.yaml | 13 + tests/e2e/webhook_suite_test.go | 250 +++++++++---------- 10 files changed, 250 insertions(+), 125 deletions(-) diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml index be656206..36524e85 100644 --- a/config/certmanager/certificate.yaml +++ b/config/certmanager/certificate.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # The following manifests contain a self-signed issuer CR and a certificate CR. # More document can be found at https://docs.cert-manager.io # WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml index bebea5a5..d672dfd8 100644 --- a/config/certmanager/kustomization.yaml +++ b/config/certmanager/kustomization.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + resources: - certificate.yaml diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml index e631f777..34e4c9c8 100644 --- a/config/certmanager/kustomizeconfig.yaml +++ b/config/certmanager/kustomizeconfig.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # This configuration is for teaching kustomize how to update name ref and var substitution nameReference: - kind: Issuer diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml index 738de350..c8b4d999 100644 --- a/config/default/manager_webhook_patch.yaml +++ b/config/default/manager_webhook_patch.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + apiVersion: apps/v1 kind: Deployment metadata: diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml index 466ed14b..e369d725 100644 --- a/config/default/webhookcainjection_patch.yaml +++ b/config/default/webhookcainjection_patch.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # This patch add annotation to admission webhook config and # the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. apiVersion: admissionregistration.k8s.io/v1 diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml index 9cf26134..d3e9e667 100644 --- a/config/webhook/kustomization.yaml +++ b/config/webhook/kustomization.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + resources: - manifests.yaml - service.yaml diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml index 25e21e3c..044a122c 100644 --- a/config/webhook/kustomizeconfig.yaml +++ b/config/webhook/kustomizeconfig.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # the following config is for teaching kustomize where to look at when substituting vars. # It requires kustomize v2.1.0 or newer to work properly. nameReference: diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 759eb57b..4d22c922 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml index bf199fd5..44dae0da 100644 --- a/config/webhook/service.yaml +++ b/config/webhook/service.yaml @@ -1,3 +1,16 @@ +# Copyright 2024 Greptime Team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. apiVersion: v1 kind: Service diff --git a/tests/e2e/webhook_suite_test.go b/tests/e2e/webhook_suite_test.go index 7ff6281a..7466428a 100644 --- a/tests/e2e/webhook_suite_test.go +++ b/tests/e2e/webhook_suite_test.go @@ -14,128 +14,128 @@ package e2e -import ( - "context" - "crypto/tls" - "fmt" - "net" - "path/filepath" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" - - admissionv1beta1 "k8s.io/api/admission/v1beta1" - //+kubebuilder:scaffold:imports - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/rest" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "github.com/GreptimeTeam/greptimedb-operator/apis/v1alpha1" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment -var ctx context.Context -var cancel context.CancelFunc - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "resources")}, - ErrorIfCRDPathMissing: false, - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := runtime.NewScheme() - err = v1alpha1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1beta1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - // start webhook server using Manager - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme, - LeaderElection: false, - Metrics: metricsserver.Options{ - BindAddress: "0", - }, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - }) - Expect(err).NotTo(HaveOccurred()) - - err = (&v1alpha1.GreptimeDBCluster{}).SetupWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - err = (&v1alpha1.GreptimeDBStandalone{}).SetupWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) - -}) - -var _ = AfterSuite(func() { - cancel() - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) +//import ( +// "context" +// "crypto/tls" +// "fmt" +// "net" +// "path/filepath" +// "testing" +// "time" +// +// . "github.com/onsi/ginkgo/v2" +// . "github.com/onsi/gomega" +// metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" +// "sigs.k8s.io/controller-runtime/pkg/webhook" +// +// admissionv1beta1 "k8s.io/api/admission/v1beta1" +// //+kubebuilder:scaffold:imports +// "k8s.io/apimachinery/pkg/runtime" +// "k8s.io/client-go/rest" +// ctrl "sigs.k8s.io/controller-runtime" +// "sigs.k8s.io/controller-runtime/pkg/client" +// "sigs.k8s.io/controller-runtime/pkg/envtest" +// logf "sigs.k8s.io/controller-runtime/pkg/log" +// "sigs.k8s.io/controller-runtime/pkg/log/zap" +// +// "github.com/GreptimeTeam/greptimedb-operator/apis/v1alpha1" +//) +// +//// These tests use Ginkgo (BDD-style Go testing framework). Refer to +//// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. +// +//var cfg *rest.Config +//var k8sClient client.Client +//var testEnv *envtest.Environment +//var ctx context.Context +//var cancel context.CancelFunc +// +//func TestAPIs(t *testing.T) { +// RegisterFailHandler(Fail) +// +// RunSpecs(t, "Webhook Suite") +//} +// +//var _ = BeforeSuite(func() { +// logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +// +// ctx, cancel = context.WithCancel(context.TODO()) +// +// By("bootstrapping test environment") +// testEnv = &envtest.Environment{ +// CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "resources")}, +// ErrorIfCRDPathMissing: false, +// WebhookInstallOptions: envtest.WebhookInstallOptions{ +// Paths: []string{filepath.Join("..", "..", "config", "webhook")}, +// }, +// } +// +// var err error +// // cfg is defined in this file globally. +// cfg, err = testEnv.Start() +// Expect(err).NotTo(HaveOccurred()) +// Expect(cfg).NotTo(BeNil()) +// +// scheme := runtime.NewScheme() +// err = v1alpha1.AddToScheme(scheme) +// Expect(err).NotTo(HaveOccurred()) +// +// err = admissionv1beta1.AddToScheme(scheme) +// Expect(err).NotTo(HaveOccurred()) +// +// //+kubebuilder:scaffold:scheme +// +// k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) +// Expect(err).NotTo(HaveOccurred()) +// Expect(k8sClient).NotTo(BeNil()) +// +// // start webhook server using Manager +// webhookInstallOptions := &testEnv.WebhookInstallOptions +// mgr, err := ctrl.NewManager(cfg, ctrl.Options{ +// Scheme: scheme, +// LeaderElection: false, +// Metrics: metricsserver.Options{ +// BindAddress: "0", +// }, +// WebhookServer: webhook.NewServer(webhook.Options{ +// Host: webhookInstallOptions.LocalServingHost, +// Port: webhookInstallOptions.LocalServingPort, +// CertDir: webhookInstallOptions.LocalServingCertDir, +// }), +// }) +// Expect(err).NotTo(HaveOccurred()) +// +// err = (&v1alpha1.GreptimeDBCluster{}).SetupWebhookWithManager(mgr) +// Expect(err).NotTo(HaveOccurred()) +// +// err = (&v1alpha1.GreptimeDBStandalone{}).SetupWebhookWithManager(mgr) +// Expect(err).NotTo(HaveOccurred()) +// +// //+kubebuilder:scaffold:webhook +// +// go func() { +// defer GinkgoRecover() +// err = mgr.Start(ctx) +// Expect(err).NotTo(HaveOccurred()) +// }() +// +// // wait for the webhook server to get ready +// dialer := &net.Dialer{Timeout: time.Second} +// addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) +// Eventually(func() error { +// conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) +// if err != nil { +// return err +// } +// conn.Close() +// return nil +// }).Should(Succeed()) +// +//}) +// +//var _ = AfterSuite(func() { +// cancel() +// By("tearing down the test environment") +// err := testEnv.Stop() +// Expect(err).NotTo(HaveOccurred()) +//}) From 5ec8092d2b96f37e2aced22a543e8975a097719c Mon Sep 17 00:00:00 2001 From: liyang Date: Tue, 17 Dec 2024 00:20:00 +0800 Subject: [PATCH 4/6] refactor: generate code --- config/webhook/manifests.yaml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 4d22c922..759eb57b 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -1,17 +1,3 @@ -# Copyright 2024 Greptime Team -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration From 47f01ef51c60645cc22cf1831b670ff189d6ee8e Mon Sep 17 00:00:00 2001 From: liyang Date: Tue, 17 Dec 2024 00:29:48 +0800 Subject: [PATCH 5/6] refactor: remove test file --- tests/e2e/webhook_suite_test.go | 141 -------------------------------- 1 file changed, 141 deletions(-) delete mode 100644 tests/e2e/webhook_suite_test.go diff --git a/tests/e2e/webhook_suite_test.go b/tests/e2e/webhook_suite_test.go deleted file mode 100644 index 7466428a..00000000 --- a/tests/e2e/webhook_suite_test.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2022 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package e2e - -//import ( -// "context" -// "crypto/tls" -// "fmt" -// "net" -// "path/filepath" -// "testing" -// "time" -// -// . "github.com/onsi/ginkgo/v2" -// . "github.com/onsi/gomega" -// metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" -// "sigs.k8s.io/controller-runtime/pkg/webhook" -// -// admissionv1beta1 "k8s.io/api/admission/v1beta1" -// //+kubebuilder:scaffold:imports -// "k8s.io/apimachinery/pkg/runtime" -// "k8s.io/client-go/rest" -// ctrl "sigs.k8s.io/controller-runtime" -// "sigs.k8s.io/controller-runtime/pkg/client" -// "sigs.k8s.io/controller-runtime/pkg/envtest" -// logf "sigs.k8s.io/controller-runtime/pkg/log" -// "sigs.k8s.io/controller-runtime/pkg/log/zap" -// -// "github.com/GreptimeTeam/greptimedb-operator/apis/v1alpha1" -//) -// -//// These tests use Ginkgo (BDD-style Go testing framework). Refer to -//// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. -// -//var cfg *rest.Config -//var k8sClient client.Client -//var testEnv *envtest.Environment -//var ctx context.Context -//var cancel context.CancelFunc -// -//func TestAPIs(t *testing.T) { -// RegisterFailHandler(Fail) -// -// RunSpecs(t, "Webhook Suite") -//} -// -//var _ = BeforeSuite(func() { -// logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) -// -// ctx, cancel = context.WithCancel(context.TODO()) -// -// By("bootstrapping test environment") -// testEnv = &envtest.Environment{ -// CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "resources")}, -// ErrorIfCRDPathMissing: false, -// WebhookInstallOptions: envtest.WebhookInstallOptions{ -// Paths: []string{filepath.Join("..", "..", "config", "webhook")}, -// }, -// } -// -// var err error -// // cfg is defined in this file globally. -// cfg, err = testEnv.Start() -// Expect(err).NotTo(HaveOccurred()) -// Expect(cfg).NotTo(BeNil()) -// -// scheme := runtime.NewScheme() -// err = v1alpha1.AddToScheme(scheme) -// Expect(err).NotTo(HaveOccurred()) -// -// err = admissionv1beta1.AddToScheme(scheme) -// Expect(err).NotTo(HaveOccurred()) -// -// //+kubebuilder:scaffold:scheme -// -// k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) -// Expect(err).NotTo(HaveOccurred()) -// Expect(k8sClient).NotTo(BeNil()) -// -// // start webhook server using Manager -// webhookInstallOptions := &testEnv.WebhookInstallOptions -// mgr, err := ctrl.NewManager(cfg, ctrl.Options{ -// Scheme: scheme, -// LeaderElection: false, -// Metrics: metricsserver.Options{ -// BindAddress: "0", -// }, -// WebhookServer: webhook.NewServer(webhook.Options{ -// Host: webhookInstallOptions.LocalServingHost, -// Port: webhookInstallOptions.LocalServingPort, -// CertDir: webhookInstallOptions.LocalServingCertDir, -// }), -// }) -// Expect(err).NotTo(HaveOccurred()) -// -// err = (&v1alpha1.GreptimeDBCluster{}).SetupWebhookWithManager(mgr) -// Expect(err).NotTo(HaveOccurred()) -// -// err = (&v1alpha1.GreptimeDBStandalone{}).SetupWebhookWithManager(mgr) -// Expect(err).NotTo(HaveOccurred()) -// -// //+kubebuilder:scaffold:webhook -// -// go func() { -// defer GinkgoRecover() -// err = mgr.Start(ctx) -// Expect(err).NotTo(HaveOccurred()) -// }() -// -// // wait for the webhook server to get ready -// dialer := &net.Dialer{Timeout: time.Second} -// addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) -// Eventually(func() error { -// conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) -// if err != nil { -// return err -// } -// conn.Close() -// return nil -// }).Should(Succeed()) -// -//}) -// -//var _ = AfterSuite(func() { -// cancel() -// By("tearing down the test environment") -// err := testEnv.Stop() -// Expect(err).NotTo(HaveOccurred()) -//}) From 66c171992e7280f51d08740545c755cca3d0cef8 Mon Sep 17 00:00:00 2001 From: liyang Date: Tue, 17 Dec 2024 18:47:39 +0800 Subject: [PATCH 6/6] chore: change path --- PROJECT | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PROJECT b/PROJECT index 8c7fb638..fa3f9606 100644 --- a/PROJECT +++ b/PROJECT @@ -14,7 +14,7 @@ resources: controller: true domain: greptime.io kind: GreptimeDBCluster - path: github.com/GreptimeTeam/greptimedb-operator/api/v1alpha1 + path: github.com/GreptimeTeam/greptimedb-operator/apis/v1alpha1 version: v1alpha1 webhooks: validation: true @@ -25,7 +25,7 @@ resources: controller: true domain: greptime.io kind: GreptimeDBStandalone - path: github.com/GreptimeTeam/greptimedb-operator/api/v1alpha1 + path: github.com/GreptimeTeam/greptimedb-operator/apis/v1alpha1 version: v1alpha1 webhooks: validation: true