diff --git a/api/v1/seaweed_webhook.go b/api/v1/seaweed_webhook.go new file mode 100644 index 0000000..56b6aed --- /dev/null +++ b/api/v1/seaweed_webhook.go @@ -0,0 +1,93 @@ +/* + + +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 v1 + +import ( + "errors" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/runtime" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// log is for logging in this package. +var seaweedlog = logf.Log.WithName("seaweed-resource") + +func (r *Seaweed) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-seaweed-seaweedfs-com-v1-seaweed,mutating=true,failurePolicy=fail,groups=seaweed.seaweedfs.com,resources=seaweeds,verbs=create;update,versions=v1,name=mseaweed.kb.io + +var _ webhook.Defaulter = &Seaweed{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Seaweed) Default() { + seaweedlog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// +kubebuilder:webhook:verbs=create;update,path=/validate-seaweed-seaweedfs-com-v1-seaweed,mutating=false,failurePolicy=fail,groups=seaweed.seaweedfs.com,resources=seaweeds,versions=v1,name=vseaweed.kb.io + +var _ webhook.Validator = &Seaweed{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Seaweed) ValidateCreate() error { + seaweedlog.Info("validate create", "name", r.Name) + errs := []error{} + + // TODO(user): fill in your validation logic upon object creation. + if r.Spec.Master == nil { + errs = append(errs, errors.New("missing master spec")) + } + + if r.Spec.Volume == nil { + errs = append(errs, errors.New("missing volume spec")) + } else { + if r.Spec.Volume.Requests[corev1.ResourceStorage].Equal(resource.MustParse("0")) { + errs = append(errs, errors.New("volume storage request cannot be zero")) + } + } + + return utilerrors.NewAggregate(errs) +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Seaweed) ValidateUpdate(old runtime.Object) error { + seaweedlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Seaweed) ValidateDelete() error { + seaweedlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 5493b98..fb41496 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ package v1 import ( corev1 "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 0000000..5148573 --- /dev/null +++ b/config/webhook/manifests.yaml @@ -0,0 +1,52 @@ + +--- +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- clientConfig: + caBundle: Cg== + service: + name: webhook-service + namespace: system + path: /mutate-seaweed-seaweedfs-com-v1-seaweed + failurePolicy: Fail + name: mseaweed.kb.io + rules: + - apiGroups: + - seaweed.seaweedfs.com + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - seaweeds + +--- +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- clientConfig: + caBundle: Cg== + service: + name: webhook-service + namespace: system + path: /validate-seaweed-seaweedfs-com-v1-seaweed + failurePolicy: Fail + name: vseaweed.kb.io + rules: + - apiGroups: + - seaweed.seaweedfs.com + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - seaweeds diff --git a/main.go b/main.go index ca8885a..c35a9a0 100644 --- a/main.go +++ b/main.go @@ -75,6 +75,10 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "Seaweed") os.Exit(1) } + if err = (&seaweedv1.Seaweed{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Seaweed") + os.Exit(1) + } // +kubebuilder:scaffold:builder setupLog.Info("starting manager")