Merge pull request #55282 from mbohlool/webhooks
Automatic merge from submit-queue (batch tested with PRs 55268, 55282, 55419, 48340, 54829). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Add MutatingWebhookConfiguration type As part of Mutating Webhook support, this PR adds the configuration for Mutating webhooks. It also renames existing ReadOnly webhook configurations from ExternalAdmissionHookConfiguration to ValidatingWebhookConfiguration. As part of the process some sub-types are also renamed. Lastly, the mutating webhook configurations are sorted by name to make the serial executing of them deterministic. ref: https://github.com/kubernetes/features/issues/492 Kubernetes-commit: 61f210859d9c4bd64af254ba696f6f693596ced9
This commit is contained in:
commit
d2374206e6
File diff suppressed because it is too large
Load Diff
|
|
@ -10,8 +10,9 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = [
|
||||
"configuration_manager_test.go",
|
||||
"external_admission_hook_manager_test.go",
|
||||
"initializer_manager_test.go",
|
||||
"mutating_webhook_manager_test.go",
|
||||
"validating_webhook_manager_test.go",
|
||||
],
|
||||
importpath = "k8s.io/apiserver/pkg/admission/configuration",
|
||||
library = ":go_default_library",
|
||||
|
|
@ -29,8 +30,9 @@ go_library(
|
|||
name = "go_default_library",
|
||||
srcs = [
|
||||
"configuration_manager.go",
|
||||
"external_admission_hook_manager.go",
|
||||
"initializer_manager.go",
|
||||
"mutating_webhook_manager.go",
|
||||
"validating_webhook_manager.go",
|
||||
],
|
||||
importpath = "k8s.io/apiserver/pkg/admission/configuration",
|
||||
deps = [
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type ExternalAdmissionHookConfigurationLister interface {
|
||||
List(opts metav1.ListOptions) (*v1alpha1.ExternalAdmissionHookConfigurationList, error)
|
||||
}
|
||||
|
||||
type ExternalAdmissionHookConfigurationManager struct {
|
||||
*poller
|
||||
}
|
||||
|
||||
func NewExternalAdmissionHookConfigurationManager(c ExternalAdmissionHookConfigurationLister) *ExternalAdmissionHookConfigurationManager {
|
||||
getFn := func() (runtime.Object, error) {
|
||||
list, err := c.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) || errors.IsForbidden(err) {
|
||||
glog.V(5).Infof("ExternalAdmissionHookConfiguration are disabled due to an error: %v", err)
|
||||
return nil, ErrDisabled
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return mergeExternalAdmissionHookConfigurations(list), nil
|
||||
}
|
||||
|
||||
return &ExternalAdmissionHookConfigurationManager{
|
||||
newPoller(getFn),
|
||||
}
|
||||
}
|
||||
|
||||
// ExternalAdmissionHooks returns the merged ExternalAdmissionHookConfiguration.
|
||||
func (im *ExternalAdmissionHookConfigurationManager) ExternalAdmissionHooks() (*v1alpha1.ExternalAdmissionHookConfiguration, error) {
|
||||
configuration, err := im.poller.configuration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
externalAdmissionHookConfiguration, ok := configuration.(*v1alpha1.ExternalAdmissionHookConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(externalAdmissionHookConfiguration), reflect.TypeOf(configuration))
|
||||
}
|
||||
return externalAdmissionHookConfiguration, nil
|
||||
}
|
||||
|
||||
func (im *ExternalAdmissionHookConfigurationManager) Run(stopCh <-chan struct{}) {
|
||||
im.poller.Run(stopCh)
|
||||
}
|
||||
|
||||
func mergeExternalAdmissionHookConfigurations(
|
||||
list *v1alpha1.ExternalAdmissionHookConfigurationList,
|
||||
) *v1alpha1.ExternalAdmissionHookConfiguration {
|
||||
configurations := list.Items
|
||||
var ret v1alpha1.ExternalAdmissionHookConfiguration
|
||||
for _, c := range configurations {
|
||||
ret.ExternalAdmissionHooks = append(ret.ExternalAdmissionHooks, c.ExternalAdmissionHooks...)
|
||||
}
|
||||
return &ret
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type MutatingWebhookConfigurationLister interface {
|
||||
List(opts metav1.ListOptions) (*v1alpha1.MutatingWebhookConfigurationList, error)
|
||||
}
|
||||
|
||||
// MutatingWebhookConfigurationManager collects the mutating webhook objects so that they can be called.
|
||||
type MutatingWebhookConfigurationManager struct {
|
||||
*poller
|
||||
}
|
||||
|
||||
func NewMutatingWebhookConfigurationManager(c MutatingWebhookConfigurationLister) *MutatingWebhookConfigurationManager {
|
||||
getFn := func() (runtime.Object, error) {
|
||||
list, err := c.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) || errors.IsForbidden(err) {
|
||||
glog.V(5).Infof("MutatingWebhookConfiguration are disabled due to an error: %v", err)
|
||||
return nil, ErrDisabled
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return mergeMutatingWebhookConfigurations(list), nil
|
||||
}
|
||||
|
||||
return &MutatingWebhookConfigurationManager{
|
||||
newPoller(getFn),
|
||||
}
|
||||
}
|
||||
|
||||
// Webhooks returns the merged MutatingWebhookConfiguration.
|
||||
func (im *MutatingWebhookConfigurationManager) Webhooks() (*v1alpha1.MutatingWebhookConfiguration, error) {
|
||||
configuration, err := im.poller.configuration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutatingWebhookConfiguration, ok := configuration.(*v1alpha1.MutatingWebhookConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(mutatingWebhookConfiguration), reflect.TypeOf(configuration))
|
||||
}
|
||||
return mutatingWebhookConfiguration, nil
|
||||
}
|
||||
|
||||
func (im *MutatingWebhookConfigurationManager) Run(stopCh <-chan struct{}) {
|
||||
im.poller.Run(stopCh)
|
||||
}
|
||||
|
||||
func mergeMutatingWebhookConfigurations(
|
||||
list *v1alpha1.MutatingWebhookConfigurationList,
|
||||
) *v1alpha1.MutatingWebhookConfiguration {
|
||||
configurations := append([]v1alpha1.MutatingWebhookConfiguration{}, list.Items...)
|
||||
var ret v1alpha1.MutatingWebhookConfiguration
|
||||
// The internal order of webhooks for each configuration is provided by the user
|
||||
// but configurations themselves can be in any order. As we are going to run these
|
||||
// webhooks in serial, they are sorted here to have a deterministic order.
|
||||
sort.Sort(byName(configurations))
|
||||
for _, c := range configurations {
|
||||
ret.Webhooks = append(ret.Webhooks, c.Webhooks...)
|
||||
}
|
||||
return &ret
|
||||
}
|
||||
|
||||
// byName sorts MutatingWebhookConfiguration by name. These objects are all in
|
||||
// cluster namespace (aka no namespace) thus they all have unique names.
|
||||
type byName []v1alpha1.MutatingWebhookConfiguration
|
||||
|
||||
func (x byName) Len() int { return len(x) }
|
||||
|
||||
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
func (x byName) Less(i, j int) bool {
|
||||
return x[i].ObjectMeta.Name < x[j].ObjectMeta.Name
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 configuration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type disabledMutatingWebhookConfigLister struct{}
|
||||
|
||||
func (l *disabledMutatingWebhookConfigLister) List(options metav1.ListOptions) (*v1alpha1.MutatingWebhookConfigurationList, error) {
|
||||
return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "MutatingWebhookConfigurations"}, "")
|
||||
}
|
||||
func TestMutatingWebhookConfigDisabled(t *testing.T) {
|
||||
manager := NewMutatingWebhookConfigurationManager(&disabledMutatingWebhookConfigLister{})
|
||||
manager.sync()
|
||||
_, err := manager.Webhooks()
|
||||
if err.Error() != ErrDisabled.Error() {
|
||||
t.Errorf("expected %v, got %v", ErrDisabled, err)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type ValidatingWebhookConfigurationLister interface {
|
||||
List(opts metav1.ListOptions) (*v1alpha1.ValidatingWebhookConfigurationList, error)
|
||||
}
|
||||
|
||||
// ValidatingWebhookConfigurationManager collects the validating webhook objects so that they can be called.
|
||||
type ValidatingWebhookConfigurationManager struct {
|
||||
*poller
|
||||
}
|
||||
|
||||
func NewValidatingWebhookConfigurationManager(c ValidatingWebhookConfigurationLister) *ValidatingWebhookConfigurationManager {
|
||||
getFn := func() (runtime.Object, error) {
|
||||
list, err := c.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) || errors.IsForbidden(err) {
|
||||
glog.V(5).Infof("ValidatingWebhookConfiguration are disabled due to an error: %v", err)
|
||||
return nil, ErrDisabled
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return mergeValidatingWebhookConfigurations(list), nil
|
||||
}
|
||||
|
||||
return &ValidatingWebhookConfigurationManager{
|
||||
newPoller(getFn),
|
||||
}
|
||||
}
|
||||
|
||||
// Webhooks returns the merged ValidatingWebhookConfiguration.
|
||||
func (im *ValidatingWebhookConfigurationManager) Webhooks() (*v1alpha1.ValidatingWebhookConfiguration, error) {
|
||||
configuration, err := im.poller.configuration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validatingWebhookConfiguration, ok := configuration.(*v1alpha1.ValidatingWebhookConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(validatingWebhookConfiguration), reflect.TypeOf(configuration))
|
||||
}
|
||||
return validatingWebhookConfiguration, nil
|
||||
}
|
||||
|
||||
func (im *ValidatingWebhookConfigurationManager) Run(stopCh <-chan struct{}) {
|
||||
im.poller.Run(stopCh)
|
||||
}
|
||||
|
||||
func mergeValidatingWebhookConfigurations(
|
||||
list *v1alpha1.ValidatingWebhookConfigurationList,
|
||||
) *v1alpha1.ValidatingWebhookConfiguration {
|
||||
configurations := list.Items
|
||||
var ret v1alpha1.ValidatingWebhookConfiguration
|
||||
for _, c := range configurations {
|
||||
ret.Webhooks = append(ret.Webhooks, c.Webhooks...)
|
||||
}
|
||||
return &ret
|
||||
}
|
||||
|
|
@ -25,15 +25,15 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type disabledWebhookConfigLister struct{}
|
||||
type disabledValidatingWebhookConfigLister struct{}
|
||||
|
||||
func (l *disabledWebhookConfigLister) List(options metav1.ListOptions) (*v1alpha1.ExternalAdmissionHookConfigurationList, error) {
|
||||
return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "externalAdmissionHookConfigurations"}, "")
|
||||
func (l *disabledValidatingWebhookConfigLister) List(options metav1.ListOptions) (*v1alpha1.ValidatingWebhookConfigurationList, error) {
|
||||
return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "ValidatingWebhookConfigurations"}, "")
|
||||
}
|
||||
func TestWebhookConfigDisabled(t *testing.T) {
|
||||
manager := NewExternalAdmissionHookConfigurationManager(&disabledWebhookConfigLister{})
|
||||
manager := NewValidatingWebhookConfigurationManager(&disabledValidatingWebhookConfigLister{})
|
||||
manager.sync()
|
||||
_, err := manager.ExternalAdmissionHooks()
|
||||
_, err := manager.Webhooks()
|
||||
if err.Error() != ErrDisabled.Error() {
|
||||
t.Errorf("expected %v, got %v", ErrDisabled, err)
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ func Register(plugins *admission.Plugins) {
|
|||
// WebhookSource can list dynamic webhook plugins.
|
||||
type WebhookSource interface {
|
||||
Run(stopCh <-chan struct{})
|
||||
ExternalAdmissionHooks() (*v1alpha1.ExternalAdmissionHookConfiguration, error)
|
||||
Webhooks() (*v1alpha1.ValidatingWebhookConfiguration, error)
|
||||
}
|
||||
|
||||
// NewGenericAdmissionWebhook returns a generic admission webhook plugin.
|
||||
|
|
@ -153,7 +153,7 @@ func (a *GenericAdmissionWebhook) SetScheme(scheme *runtime.Scheme) {
|
|||
|
||||
// WantsExternalKubeClientSet defines a function which sets external ClientSet for admission plugins that need it
|
||||
func (a *GenericAdmissionWebhook) SetExternalKubeClientSet(client clientset.Interface) {
|
||||
a.hookSource = configuration.NewExternalAdmissionHookConfigurationManager(client.AdmissionregistrationV1alpha1().ExternalAdmissionHookConfigurations())
|
||||
a.hookSource = configuration.NewValidatingWebhookConfigurationManager(client.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations())
|
||||
}
|
||||
|
||||
// ValidateInitialization implements the InitializationValidator interface.
|
||||
|
|
@ -168,19 +168,19 @@ func (a *GenericAdmissionWebhook) ValidateInitialization() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (a *GenericAdmissionWebhook) loadConfiguration(attr admission.Attributes) (*v1alpha1.ExternalAdmissionHookConfiguration, error) {
|
||||
hookConfig, err := a.hookSource.ExternalAdmissionHooks()
|
||||
// if ExternalAdmissionHook configuration is disabled, fail open
|
||||
func (a *GenericAdmissionWebhook) loadConfiguration(attr admission.Attributes) (*v1alpha1.ValidatingWebhookConfiguration, error) {
|
||||
hookConfig, err := a.hookSource.Webhooks()
|
||||
// if Webhook configuration is disabled, fail open
|
||||
if err == configuration.ErrDisabled {
|
||||
return &v1alpha1.ExternalAdmissionHookConfiguration{}, nil
|
||||
return &v1alpha1.ValidatingWebhookConfiguration{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
e := apierrors.NewServerTimeout(attr.GetResource().GroupResource(), string(attr.GetOperation()), 1)
|
||||
e.ErrStatus.Message = fmt.Sprintf("Unable to refresh the ExternalAdmissionHook configuration: %v", err)
|
||||
e.ErrStatus.Message = fmt.Sprintf("Unable to refresh the Webhook configuration: %v", err)
|
||||
e.ErrStatus.Reason = "LoadingConfiguration"
|
||||
e.ErrStatus.Details.Causes = append(e.ErrStatus.Details.Causes, metav1.StatusCause{
|
||||
Type: "ExternalAdmissionHookConfigurationFailure",
|
||||
Message: "An error has occurred while refreshing the externalAdmissionHook configuration, no resources can be created/updated/deleted/connected until a refresh succeeds.",
|
||||
Type: "ValidatingWebhookConfigurationFailure",
|
||||
Message: "An error has occurred while refreshing the ValidatingWebhook configuration, no resources can be created/updated/deleted/connected until a refresh succeeds.",
|
||||
})
|
||||
return nil, e
|
||||
}
|
||||
|
|
@ -193,14 +193,14 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hooks := hookConfig.ExternalAdmissionHooks
|
||||
hooks := hookConfig.Webhooks
|
||||
ctx := context.TODO()
|
||||
|
||||
errCh := make(chan error, len(hooks))
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(hooks))
|
||||
for i := range hooks {
|
||||
go func(hook *v1alpha1.ExternalAdmissionHook) {
|
||||
go func(hook *v1alpha1.Webhook) {
|
||||
defer wg.Done()
|
||||
|
||||
err := a.callHook(ctx, hook, attr)
|
||||
|
|
@ -245,7 +245,7 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error {
|
|||
return errs[0]
|
||||
}
|
||||
|
||||
func (a *GenericAdmissionWebhook) callHook(ctx context.Context, h *v1alpha1.ExternalAdmissionHook, attr admission.Attributes) error {
|
||||
func (a *GenericAdmissionWebhook) callHook(ctx context.Context, h *v1alpha1.Webhook, attr admission.Attributes) error {
|
||||
matches := false
|
||||
for _, r := range h.Rules {
|
||||
m := RuleMatcher{Rule: r, Attr: attr}
|
||||
|
|
@ -299,7 +299,7 @@ func toStatusErr(name string, result *metav1.Status) *apierrors.StatusError {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *GenericAdmissionWebhook) hookClient(h *v1alpha1.ExternalAdmissionHook) (*rest.RESTClient, error) {
|
||||
func (a *GenericAdmissionWebhook) hookClient(h *v1alpha1.Webhook) (*rest.RESTClient, error) {
|
||||
serverName := h.ClientConfig.Service.Name + "." + h.ClientConfig.Service.Namespace + ".svc"
|
||||
u, err := a.serviceResolver.ResolveEndpoint(h.ClientConfig.Service.Namespace, h.ClientConfig.Service.Name)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -39,15 +39,15 @@ import (
|
|||
)
|
||||
|
||||
type fakeHookSource struct {
|
||||
hooks []registrationv1alpha1.ExternalAdmissionHook
|
||||
hooks []registrationv1alpha1.Webhook
|
||||
err error
|
||||
}
|
||||
|
||||
func (f *fakeHookSource) ExternalAdmissionHooks() (*registrationv1alpha1.ExternalAdmissionHookConfiguration, error) {
|
||||
func (f *fakeHookSource) Webhooks() (*registrationv1alpha1.ValidatingWebhookConfiguration, error) {
|
||||
if f.err != nil {
|
||||
return nil, f.err
|
||||
}
|
||||
return ®istrationv1alpha1.ExternalAdmissionHookConfiguration{ExternalAdmissionHooks: f.hooks}, nil
|
||||
return ®istrationv1alpha1.ValidatingWebhookConfiguration{Webhooks: f.hooks}, nil
|
||||
}
|
||||
|
||||
func (f *fakeHookSource) Run(stopCh <-chan struct{}) {}
|
||||
|
|
@ -137,8 +137,8 @@ func TestAdmit(t *testing.T) {
|
|||
expectAllow bool
|
||||
errorContains string
|
||||
}
|
||||
ccfg := func(urlPath string) registrationv1alpha1.AdmissionHookClientConfig {
|
||||
return registrationv1alpha1.AdmissionHookClientConfig{
|
||||
ccfg := func(urlPath string) registrationv1alpha1.WebhookClientConfig {
|
||||
return registrationv1alpha1.WebhookClientConfig{
|
||||
Service: registrationv1alpha1.ServiceReference{
|
||||
Name: "webhook-test",
|
||||
Namespace: "default",
|
||||
|
|
@ -163,7 +163,7 @@ func TestAdmit(t *testing.T) {
|
|||
table := map[string]test{
|
||||
"no match": {
|
||||
hookSource: fakeHookSource{
|
||||
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
|
||||
hooks: []registrationv1alpha1.Webhook{{
|
||||
Name: "nomatch",
|
||||
ClientConfig: ccfg("disallow"),
|
||||
Rules: []registrationv1alpha1.RuleWithOperations{{
|
||||
|
|
@ -175,7 +175,7 @@ func TestAdmit(t *testing.T) {
|
|||
},
|
||||
"match & allow": {
|
||||
hookSource: fakeHookSource{
|
||||
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
|
||||
hooks: []registrationv1alpha1.Webhook{{
|
||||
Name: "allow",
|
||||
ClientConfig: ccfg("allow"),
|
||||
Rules: matchEverythingRules,
|
||||
|
|
@ -185,7 +185,7 @@ func TestAdmit(t *testing.T) {
|
|||
},
|
||||
"match & disallow": {
|
||||
hookSource: fakeHookSource{
|
||||
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
|
||||
hooks: []registrationv1alpha1.Webhook{{
|
||||
Name: "disallow",
|
||||
ClientConfig: ccfg("disallow"),
|
||||
Rules: matchEverythingRules,
|
||||
|
|
@ -195,7 +195,7 @@ func TestAdmit(t *testing.T) {
|
|||
},
|
||||
"match & disallow ii": {
|
||||
hookSource: fakeHookSource{
|
||||
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
|
||||
hooks: []registrationv1alpha1.Webhook{{
|
||||
Name: "disallowReason",
|
||||
ClientConfig: ccfg("disallowReason"),
|
||||
Rules: matchEverythingRules,
|
||||
|
|
@ -205,7 +205,7 @@ func TestAdmit(t *testing.T) {
|
|||
},
|
||||
"match & fail (but allow because fail open)": {
|
||||
hookSource: fakeHookSource{
|
||||
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
|
||||
hooks: []registrationv1alpha1.Webhook{{
|
||||
Name: "internalErr A",
|
||||
ClientConfig: ccfg("internalErr"),
|
||||
Rules: matchEverythingRules,
|
||||
|
|
@ -226,7 +226,7 @@ func TestAdmit(t *testing.T) {
|
|||
},
|
||||
"match & fail (but disallow because fail closed on nil)": {
|
||||
hookSource: fakeHookSource{
|
||||
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
|
||||
hooks: []registrationv1alpha1.Webhook{{
|
||||
Name: "internalErr A",
|
||||
ClientConfig: ccfg("internalErr"),
|
||||
Rules: matchEverythingRules,
|
||||
|
|
@ -244,7 +244,7 @@ func TestAdmit(t *testing.T) {
|
|||
},
|
||||
"match & fail (but fail because fail closed)": {
|
||||
hookSource: fakeHookSource{
|
||||
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
|
||||
hooks: []registrationv1alpha1.Webhook{{
|
||||
Name: "internalErr A",
|
||||
ClientConfig: ccfg("internalErr"),
|
||||
Rules: matchEverythingRules,
|
||||
|
|
|
|||
Loading…
Reference in New Issue