Clean up webhook handler interface
Signed-off-by: James Munnelly <james@munnelly.eu>
This commit is contained in:
parent
ee9cbf25af
commit
ca9e8f33b2
@ -59,8 +59,8 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
var validationHook handlers.ValidatingAdmissionHook = handlers.NewFuncBackedValidator(logs.Log, GroupName, webhook.Scheme, validationFuncs)
|
||||
var mutationHook handlers.MutatingAdmissionHook = handlers.NewSchemeBackedDefaulter(logs.Log, GroupName, webhook.Scheme)
|
||||
var validationHook handlers.ValidatingAdmissionHook = handlers.NewFuncBackedValidator(logs.Log, webhook.Scheme, validationFuncs)
|
||||
var mutationHook handlers.MutatingAdmissionHook = handlers.NewSchemeBackedDefaulter(logs.Log, webhook.Scheme)
|
||||
|
||||
func main() {
|
||||
klog.InitFlags(flag.CommandLine)
|
||||
|
||||
@ -19,7 +19,6 @@ go_library(
|
||||
"@io_k8s_apimachinery//pkg/runtime/serializer:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime/serializer/json:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/util/validation/field:go_default_library",
|
||||
"@io_k8s_client_go//rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -28,7 +27,6 @@ go_test(
|
||||
srcs = ["mutation_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/webhook/handlers/testdata/apis/testgroup:go_default_library",
|
||||
"//pkg/webhook/handlers/testdata/apis/testgroup/install:go_default_library",
|
||||
"@com_github_mattbaird_jsonpatch//:go_default_library",
|
||||
"@io_k8s_api//admission/v1beta1:go_default_library",
|
||||
|
||||
@ -18,37 +18,16 @@ package handlers
|
||||
|
||||
import (
|
||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type AdmissionHook interface {
|
||||
// Initialize is called as a post-start hook
|
||||
Initialize(kubeClientConfig *restclient.Config, stopCh <-chan struct{}) error
|
||||
}
|
||||
|
||||
type ValidatingAdmissionHook interface {
|
||||
AdmissionHook
|
||||
|
||||
// ValidatingResource is the resource to use for hosting your admission webhook. If the hook implements
|
||||
// MutatingAdmissionHook as well, the two resources for validating and mutating admission must be different.
|
||||
// Note: this is (usually) not the same as the payload resource!
|
||||
ValidatingResource() (plural schema.GroupVersionResource, singular string)
|
||||
|
||||
// Validate is called to decide whether to accept the admission request. The returned AdmissionResponse
|
||||
// must not use the Patch field.
|
||||
Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
|
||||
}
|
||||
|
||||
type MutatingAdmissionHook interface {
|
||||
AdmissionHook
|
||||
|
||||
// MutatingResource is the resource to use for hosting your admission webhook. If the hook implements
|
||||
// ValidatingAdmissionHook as well, the two resources for validating and mutating admission must be different.
|
||||
// Note: this is (usually) not the same as the payload resource!
|
||||
MutatingResource() (plural schema.GroupVersionResource, singular string)
|
||||
|
||||
// Admit is called to decide whether to accept the admission request. The returned AdmissionResponse may
|
||||
// use the Patch field to mutate the object from the passed AdmissionRequest.
|
||||
Admit(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
|
||||
Mutate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
|
||||
}
|
||||
|
||||
@ -28,43 +28,29 @@ import (
|
||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
apijson "k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type SchemeBackedDefaulter struct {
|
||||
log logr.Logger
|
||||
groupName string
|
||||
scheme *runtime.Scheme
|
||||
codec runtime.Codec
|
||||
log logr.Logger
|
||||
scheme *runtime.Scheme
|
||||
codec runtime.Codec
|
||||
}
|
||||
|
||||
func NewSchemeBackedDefaulter(log logr.Logger, groupName string, scheme *runtime.Scheme) *SchemeBackedDefaulter {
|
||||
func NewSchemeBackedDefaulter(log logr.Logger, scheme *runtime.Scheme) *SchemeBackedDefaulter {
|
||||
factory := serializer.NewCodecFactory(scheme)
|
||||
serializer := apijson.NewSerializerWithOptions(apijson.DefaultMetaFactory, scheme, scheme, apijson.SerializerOptions{})
|
||||
encoder := factory.WithoutConversion().EncoderForVersion(serializer, nil)
|
||||
decoder := factory.UniversalDeserializer()
|
||||
return &SchemeBackedDefaulter{
|
||||
log: log,
|
||||
groupName: groupName,
|
||||
scheme: scheme,
|
||||
codec: runtime.NewCodec(encoder, decoder),
|
||||
log: log,
|
||||
scheme: scheme,
|
||||
codec: runtime.NewCodec(encoder, decoder),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *SchemeBackedDefaulter) Initialize(kubeClientConfig *restclient.Config, stopCh <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *SchemeBackedDefaulter) MutatingResource() (plural schema.GroupVersionResource, singular string) {
|
||||
gv := admissionv1beta1.SchemeGroupVersion
|
||||
gv.Group = c.groupName
|
||||
return gv.WithResource("mutations"), "mutation"
|
||||
}
|
||||
|
||||
func (c *SchemeBackedDefaulter) Admit(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse {
|
||||
func (c *SchemeBackedDefaulter) Mutate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse {
|
||||
status := &admissionv1beta1.AdmissionResponse{}
|
||||
|
||||
// decode the raw object data
|
||||
|
||||
@ -29,7 +29,6 @@ import (
|
||||
"k8s.io/klog/klogr"
|
||||
"k8s.io/utils/diff"
|
||||
|
||||
"github.com/jetstack/cert-manager/pkg/webhook/handlers/testdata/apis/testgroup"
|
||||
"github.com/jetstack/cert-manager/pkg/webhook/handlers/testdata/apis/testgroup/install"
|
||||
)
|
||||
|
||||
@ -52,7 +51,7 @@ func TestDefaultCertificate(t *testing.T) {
|
||||
|
||||
log := klogr.New()
|
||||
klog.InitFlags(flag.CommandLine)
|
||||
c := NewSchemeBackedDefaulter(log, testgroup.GroupName, scheme)
|
||||
c := NewSchemeBackedDefaulter(log, scheme)
|
||||
tests := map[string]testT{
|
||||
"apply defaults to TestType": {
|
||||
inputRequest: admissionv1beta1.AdmissionRequest{
|
||||
@ -91,7 +90,7 @@ func TestDefaultCertificate(t *testing.T) {
|
||||
|
||||
for n, test := range tests {
|
||||
t.Run(n, func(t *testing.T) {
|
||||
runTest(t, c.Admit, test)
|
||||
runTest(t, c.Mutate, test)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -101,9 +100,9 @@ type testT struct {
|
||||
expectedResponse admissionv1beta1.AdmissionResponse
|
||||
}
|
||||
|
||||
type mutateFn func(request *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
|
||||
type admitFn func(request *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
|
||||
|
||||
func runTest(t *testing.T, fn mutateFn, test testT) {
|
||||
func runTest(t *testing.T, fn admitFn, test testT) {
|
||||
resp := fn(&test.inputRequest)
|
||||
if !reflect.DeepEqual(&test.expectedResponse, resp) {
|
||||
t.Errorf("Response was not as expected: %v", diff.ObjectGoPrintSideBySide(&test.expectedResponse, resp))
|
||||
|
||||
@ -27,21 +27,18 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type funcBackedValidator struct {
|
||||
log logr.Logger
|
||||
groupName string
|
||||
decoder runtime.Decoder
|
||||
validations map[schema.GroupVersionKind]ValidationFunc
|
||||
}
|
||||
|
||||
func NewFuncBackedValidator(log logr.Logger, groupName string, scheme *runtime.Scheme, fns map[schema.GroupVersionKind]ValidationFunc) *funcBackedValidator {
|
||||
func NewFuncBackedValidator(log logr.Logger, scheme *runtime.Scheme, fns map[schema.GroupVersionKind]ValidationFunc) *funcBackedValidator {
|
||||
factory := serializer.NewCodecFactory(scheme)
|
||||
return &funcBackedValidator{
|
||||
log: log,
|
||||
groupName: groupName,
|
||||
log: log,
|
||||
// TODO: switch to using UniversalDecoder and make validation functions
|
||||
// run against the internal apiversion
|
||||
decoder: factory.UniversalDeserializer(),
|
||||
@ -51,16 +48,6 @@ func NewFuncBackedValidator(log logr.Logger, groupName string, scheme *runtime.S
|
||||
|
||||
type ValidationFunc func(runtime.Object) field.ErrorList
|
||||
|
||||
func (c *funcBackedValidator) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *funcBackedValidator) ValidatingResource() (plural schema.GroupVersionResource, singular string) {
|
||||
gv := admissionv1beta1.SchemeGroupVersion
|
||||
gv.Group = c.groupName
|
||||
return gv.WithResource("validations"), "validation"
|
||||
}
|
||||
|
||||
func (c *funcBackedValidator) Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse {
|
||||
status := &admissionv1beta1.AdmissionResponse{}
|
||||
|
||||
|
||||
@ -240,7 +240,7 @@ func (s *Server) validate(obj runtime.Object) runtime.Object {
|
||||
|
||||
func (s *Server) mutate(obj runtime.Object) runtime.Object {
|
||||
review := obj.(*admissionv1beta1.AdmissionReview)
|
||||
resp := s.MutationWebhook.Admit(review.Request)
|
||||
resp := s.MutationWebhook.Mutate(review.Request)
|
||||
review.Response = resp
|
||||
return review
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user