From 03a80ec0ce55bc5e3f278160ba46897d6688c507 Mon Sep 17 00:00:00 2001 From: Zhuxiaoyang Date: Mon, 23 Sep 2019 21:25:56 +0800 Subject: [PATCH] add mutatingwebhook (#104) Signed-off-by: zhuxiaoyang --- pkg/webhook/default_server/add_validating.go | 25 +++++++ .../mutating/create_update_webhook.go | 22 ++++++ .../s2ibuilder/mutating/mutate.go | 1 + .../s2ibuilder_create_update_handler.go | 69 +++++++++++++++++++ .../s2ibuilder/mutating/webhooks.go | 13 ++++ .../s2irun_create_update_handler.go | 2 +- 6 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 pkg/webhook/default_server/s2ibuilder/mutating/create_update_webhook.go create mode 100644 pkg/webhook/default_server/s2ibuilder/mutating/mutate.go create mode 100644 pkg/webhook/default_server/s2ibuilder/mutating/s2ibuilder_create_update_handler.go create mode 100644 pkg/webhook/default_server/s2ibuilder/mutating/webhooks.go diff --git a/pkg/webhook/default_server/add_validating.go b/pkg/webhook/default_server/add_validating.go index 759a90ef..efa8409d 100644 --- a/pkg/webhook/default_server/add_validating.go +++ b/pkg/webhook/default_server/add_validating.go @@ -19,6 +19,7 @@ package defaultserver import ( "fmt" + s2iBuilderMutating "github.com/kubesphere/s2ioperator/pkg/webhook/default_server/s2ibuilder/mutating" s2iBuilderValidating "github.com/kubesphere/s2ioperator/pkg/webhook/default_server/s2ibuilder/validating" s2iBuilderTemplateValidating "github.com/kubesphere/s2ioperator/pkg/webhook/default_server/s2ibuildertemplate/validating" s2iRunValidating "github.com/kubesphere/s2ioperator/pkg/webhook/default_server/s2irun/validating" @@ -94,4 +95,28 @@ func init() { } HandlerMap[k] = v } + + for k, v := range s2iBuilderMutating.Builders { + _, found := builderMap[k] + if found { + log.V(1).Info(fmt.Sprintf( + "conflicting webhook builder names in builder map: %v", k)) + } + builderMap[k] = v + } + + for k, v := range s2iBuilderMutating.HandlerMap { + _, found := HandlerMap[k] + if found { + log.V(1).Info(fmt.Sprintf( + "conflicting webhook builder names in handler map: %v", k)) + } + _, found = builderMap[k] + if !found { + log.V(1).Info(fmt.Sprintf( + "can't find webhook builder name %q in builder map", k)) + continue + } + HandlerMap[k] = v + } } diff --git a/pkg/webhook/default_server/s2ibuilder/mutating/create_update_webhook.go b/pkg/webhook/default_server/s2ibuilder/mutating/create_update_webhook.go new file mode 100644 index 00000000..0d20afb4 --- /dev/null +++ b/pkg/webhook/default_server/s2ibuilder/mutating/create_update_webhook.go @@ -0,0 +1,22 @@ +package mutating + +import ( + devopsv1alpha1 "github.com/kubesphere/s2ioperator/pkg/apis/devops/v1alpha1" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder" +) + +var logger = log.Log.WithName("s2ibuilder-mutate") + +func init() { + builderName := "mutating-create-s2ibuilder" + Builders[builderName] = builder. + NewWebhookBuilder(). + Name(builderName+".kubesphere.io"). + Path("/"+builderName). + Mutating(). + Operations(admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update). + FailurePolicy(admissionregistrationv1beta1.Fail). + ForType(&devopsv1alpha1.S2iBuilder{}) +} diff --git a/pkg/webhook/default_server/s2ibuilder/mutating/mutate.go b/pkg/webhook/default_server/s2ibuilder/mutating/mutate.go new file mode 100644 index 00000000..439bad23 --- /dev/null +++ b/pkg/webhook/default_server/s2ibuilder/mutating/mutate.go @@ -0,0 +1 @@ +package mutating diff --git a/pkg/webhook/default_server/s2ibuilder/mutating/s2ibuilder_create_update_handler.go b/pkg/webhook/default_server/s2ibuilder/mutating/s2ibuilder_create_update_handler.go new file mode 100644 index 00000000..5eed8d45 --- /dev/null +++ b/pkg/webhook/default_server/s2ibuilder/mutating/s2ibuilder_create_update_handler.go @@ -0,0 +1,69 @@ +package mutating + +import ( + "context" + devopsv1alpha1 "github.com/kubesphere/s2ioperator/pkg/apis/devops/v1alpha1" + "net/http" + "sigs.k8s.io/controller-runtime/pkg/runtime/inject" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission/types" +) + +const ( + DefaultRevisionId = "master" + DefaultTag = "latest" +) + +func init() { + webhookName := "mutating-create-s2ibuilder" + if HandlerMap[webhookName] == nil { + HandlerMap[webhookName] = []admission.Handler{} + } + HandlerMap[webhookName] = append(HandlerMap[webhookName], &S2iBuilderCreateHandler{}) +} + +// S2iBuilderCreateHandler handles S2iBuilder +type S2iBuilderCreateHandler struct { + Decoder types.Decoder +} + +// Implement admission.Handler so the controller can handle admission request. +var _ admission.Handler = &S2iBuilderCreateHandler{} + +// S2iBuilderCreateHandler adds an default status info to S2iBuilder +func (h *S2iBuilderCreateHandler) Handle(ctx context.Context, req types.Request) types.Response { + s2ibuilder := &devopsv1alpha1.S2iBuilder{} + err := h.Decoder.Decode(req, s2ibuilder) + + if err != nil { + return admission.ErrorResponse(http.StatusBadRequest, err) + } + s2ib := s2ibuilder.DeepCopy() + + err = h.mutatingS2iBuilderFn(ctx, s2ib) + if err != nil { + return admission.ErrorResponse(http.StatusInternalServerError, err) + } + return admission.PatchResponse(s2ibuilder, s2ib) +} + +func (h *S2iBuilderCreateHandler) mutatingS2iBuilderFn(ctx context.Context, obj *devopsv1alpha1.S2iBuilder) error { + + if obj.Spec.Config.RevisionId == "" { + obj.Spec.Config.RevisionId = DefaultRevisionId + } + + if obj.Spec.Config.Tag == "" { + obj.Spec.Config.Tag = DefaultTag + } + + return nil +} + +var _ inject.Decoder = &S2iBuilderCreateHandler{} + +// InjectDecoder injects the decoder. +func (h *S2iBuilderCreateHandler) InjectDecoder(d types.Decoder) error { + h.Decoder = d + return nil +} diff --git a/pkg/webhook/default_server/s2ibuilder/mutating/webhooks.go b/pkg/webhook/default_server/s2ibuilder/mutating/webhooks.go new file mode 100644 index 00000000..bfc1a7d9 --- /dev/null +++ b/pkg/webhook/default_server/s2ibuilder/mutating/webhooks.go @@ -0,0 +1,13 @@ +package mutating + +import ( + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder" +) + +var ( + // Builders contain admission webhook builders + Builders = map[string]*builder.WebhookBuilder{} + // HandlerMap contains admission webhook handlers + HandlerMap = map[string][]admission.Handler{} +) diff --git a/pkg/webhook/default_server/s2irun/validating/s2irun_create_update_handler.go b/pkg/webhook/default_server/s2irun/validating/s2irun_create_update_handler.go index 484a329b..b087ca7e 100644 --- a/pkg/webhook/default_server/s2irun/validating/s2irun_create_update_handler.go +++ b/pkg/webhook/default_server/s2irun/validating/s2irun_create_update_handler.go @@ -53,7 +53,7 @@ func (h *S2iRunCreateUpdateHandler) validatingS2iRunFn(ctx context.Context, obj builder := &devopsv1alpha1.S2iBuilder{} - err := h.Client.Get(context.TODO(), types2.NamespacedName{Namespace: origin.Namespace, Name: obj.Spec.BuilderName}, builder) + err := h.Client.Get(context.TODO(), types2.NamespacedName{Namespace: obj.Namespace, Name: obj.Spec.BuilderName}, builder) if err != nil && !k8serror.IsNotFound(err) { return false, "validate failed", errors.NewFieldInvalidValueWithReason("no", "could not call k8s api") }