diff --git a/go.mod b/go.mod index 4ae37daa357..5797b5225fe 100644 --- a/go.mod +++ b/go.mod @@ -179,7 +179,7 @@ require ( go.opentelemetry.io/otel v1.23.0 // indirect go.opentelemetry.io/otel/sdk v1.22.0 // indirect go.opentelemetry.io/otel/trace v1.23.0 // indirect - go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.19.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect diff --git a/go.sum b/go.sum index a50b35db1ea..3d257e4885b 100644 --- a/go.sum +++ b/go.sum @@ -775,7 +775,6 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe h1:USL2DhxfgRchafRvt/wYyyQNzwgL7ZiURcozOE/Pkvo= google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac h1:OZkkudMUu9LVQMCoRUbI/1p5VCo9BOrlvkqMvWtqa6s= diff --git a/pkg/handler/handler.go b/pkg/handler/handler.go index 4366ea02c51..47ec922bf0d 100644 --- a/pkg/handler/handler.go +++ b/pkg/handler/handler.go @@ -27,7 +27,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - crv1alpha1 "github.com/kanisterio/kanister/pkg/apis/cr/v1alpha1" "github.com/kanisterio/kanister/pkg/validatingwebhook" "github.com/kanisterio/kanister/pkg/version" "github.com/pkg/errors" @@ -71,11 +70,14 @@ func RunWebhookServer(c *rest.Config) error { if err != nil { return errors.Wrapf(err, "Failed to create new webhook manager") } + bpValidator := &validatingwebhook.BlueprintValidator{} + if err = bpValidator.InjectDecoder(admission.NewDecoder(mgr.GetScheme())); err != nil { + return errors.Wrapf(err, "Failed to inject decoder") + } hookServerOptions := webhook.Options{CertDir: validatingwebhook.WHCertsDir} hookServer := webhook.NewServer(hookServerOptions) - hook := admission.WithCustomValidator(mgr.GetScheme(), &crv1alpha1.Blueprint{}, &validatingwebhook.BlueprintValidator{}) - hookServer.Register(whHandlePath, hook) + hookServer.Register(whHandlePath, &webhook.Admission{Handler: bpValidator}) hookServer.Register(healthCheckPath, &healthCheckHandler{}) hookServer.Register(metricsPath, promhttp.Handler()) diff --git a/pkg/validatingwebhook/blueprint_handler.go b/pkg/validatingwebhook/blueprint_handler.go index c93c6393551..ed21644e8c5 100644 --- a/pkg/validatingwebhook/blueprint_handler.go +++ b/pkg/validatingwebhook/blueprint_handler.go @@ -4,44 +4,34 @@ import ( "context" "fmt" - "k8s.io/apimachinery/pkg/runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" kanister "github.com/kanisterio/kanister/pkg" crv1alpha1 "github.com/kanisterio/kanister/pkg/apis/cr/v1alpha1" "github.com/kanisterio/kanister/pkg/blueprint/validate" + "net/http" ) -//+kubebuilder:webhook:path=validate/v1alpha1/blueprint,mutating=false,failurePolicy=fail,sideEffects=None,groups=cr.kanister.io,resources=blueprints,verbs=create,versions=v1alpha1,name=blueprint.cr.kanister.io - -type BlueprintValidator struct{} - -var _ webhook.CustomValidator = &BlueprintValidator{} +type BlueprintValidator struct { + decoder *admission.Decoder +} -func (b *BlueprintValidator) validate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - log := logf.FromContext(ctx) - bp, ok := obj.(*crv1alpha1.Blueprint) - if !ok { - return nil, fmt.Errorf("expected a Blueprint but got a %T", obj) +func (b *BlueprintValidator) Handle(ctx context.Context, r admission.Request) admission.Response { + bp := &crv1alpha1.Blueprint{} + err := b.decoder.Decode(r, bp) + if err != nil { + return admission.Errored(http.StatusBadRequest, err) } - log.Info("Validating blueprint") + if err := validate.Do(bp, kanister.DefaultVersion); err != nil { - return nil, fmt.Errorf("invalid blueprint, %s", err.Error()) + return admission.Denied(fmt.Sprintf("Invalid blueprint, %s\n", err.Error())) } - return nil, nil -} - -func (b *BlueprintValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { - return b.validate(ctx, obj) -} - -func (b *BlueprintValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { - return b.validate(ctx, newObj) + return admission.Allowed("") } -func (b BlueprintValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { - return b.validate(ctx, obj) +// InjectDecoder injects the decoder. +func (b *BlueprintValidator) InjectDecoder(d *admission.Decoder) error { + b.decoder = d + return nil }