mirror of https://github.com/k3s-io/k3s
Rename ExternalAdmissionHookConfiguration to ValidatingWebhookConfiguration
parent
e873b36a44
commit
9ddea83a2c
|
@ -680,7 +680,7 @@ func postProcessOpenAPISpecForBackwardCompatibility(s *spec.Swagger) (*spec.Swag
|
|||
compatibilityMap := map[string]string{
|
||||
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.SelfSubjectAccessReview": "io.k8s.api.authorization.v1beta1.SelfSubjectAccessReview",
|
||||
"io.k8s.kubernetes.pkg.api.v1.GitRepoVolumeSource": "io.k8s.api.core.v1.GitRepoVolumeSource",
|
||||
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ExternalAdmissionHookConfigurationList": "io.k8s.api.admissionregistration.v1alpha1.ExternalAdmissionHookConfigurationList",
|
||||
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ValidatingWebhookConfigurationList": "io.k8s.api.admissionregistration.v1alpha1.ValidatingWebhookConfigurationList",
|
||||
"io.k8s.kubernetes.pkg.api.v1.EndpointPort": "io.k8s.api.core.v1.EndpointPort",
|
||||
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.SupplementalGroupsStrategyOptions": "io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions",
|
||||
"io.k8s.kubernetes.pkg.api.v1.PodStatus": "io.k8s.api.core.v1.PodStatus",
|
||||
|
@ -778,7 +778,7 @@ func postProcessOpenAPISpecForBackwardCompatibility(s *spec.Swagger) (*spec.Swag
|
|||
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IngressSpec": "io.k8s.api.extensions.v1beta1.IngressSpec",
|
||||
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DeploymentCondition": "io.k8s.api.extensions.v1beta1.DeploymentCondition",
|
||||
"io.k8s.kubernetes.pkg.api.v1.GCEPersistentDiskVolumeSource": "io.k8s.api.core.v1.GCEPersistentDiskVolumeSource",
|
||||
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ExternalAdmissionHook": "io.k8s.api.admissionregistration.v1alpha1.ExternalAdmissionHook",
|
||||
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.Webhook": "io.k8s.api.admissionregistration.v1alpha1.Webhook",
|
||||
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.Scale": "io.k8s.api.extensions.v1beta1.Scale",
|
||||
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.HorizontalPodAutoscalerStatus": "io.k8s.api.autoscaling.v2alpha1.HorizontalPodAutoscalerStatus",
|
||||
"io.k8s.kubernetes.pkg.api.v1.FlexVolumeSource": "io.k8s.api.core.v1.FlexVolumeSource",
|
||||
|
@ -851,7 +851,7 @@ func postProcessOpenAPISpecForBackwardCompatibility(s *spec.Swagger) (*spec.Swag
|
|||
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.ScaleStatus": "io.k8s.api.apps.v1beta1.ScaleStatus",
|
||||
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.HTTPIngressRuleValue": "io.k8s.api.extensions.v1beta1.HTTPIngressRuleValue",
|
||||
"io.k8s.kubernetes.pkg.apis.batch.v1.Job": "io.k8s.api.batch.v1.Job",
|
||||
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ExternalAdmissionHookConfiguration": "io.k8s.api.admissionregistration.v1alpha1.ExternalAdmissionHookConfiguration",
|
||||
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ValidatingWebhookConfiguration": "io.k8s.api.admissionregistration.v1alpha1.ValidatingWebhookConfiguration",
|
||||
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.RoleBinding": "io.k8s.api.rbac.v1beta1.RoleBinding",
|
||||
"io.k8s.kubernetes.pkg.api.v1.FCVolumeSource": "io.k8s.api.core.v1.FCVolumeSource",
|
||||
"io.k8s.kubernetes.pkg.api.v1.EndpointAddress": "io.k8s.api.core.v1.EndpointAddress",
|
||||
|
|
|
@ -135,8 +135,8 @@ func TestDefaulting(t *testing.T) {
|
|||
{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "RoleBindingList"}: {},
|
||||
{Group: "settings.k8s.io", Version: "v1alpha1", Kind: "PodPreset"}: {},
|
||||
{Group: "settings.k8s.io", Version: "v1alpha1", Kind: "PodPresetList"}: {},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ExternalAdmissionHookConfiguration"}: {},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ExternalAdmissionHookConfigurationList"}: {},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ValidatingWebhookConfiguration"}: {},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ValidatingWebhookConfigurationList"}: {},
|
||||
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"}: {},
|
||||
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicyList"}: {},
|
||||
{Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClass"}: {},
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
|
||||
// Package admissionregistration is the internal version of the API.
|
||||
// AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration
|
||||
// InitializerConfiguration and ExternalAdmissionHookConfiguration is for the
|
||||
// InitializerConfiguration and ValidatingWebhookConfiguration is for the
|
||||
// new dynamic admission controller configuration.
|
||||
// +groupName=admissionregistration.k8s.io
|
||||
package admissionregistration // import "k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
// Funcs returns the fuzzer functions for the admissionregistration api group.
|
||||
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
return []interface{}{
|
||||
func(obj *admissionregistration.ExternalAdmissionHook, c fuzz.Continue) {
|
||||
func(obj *admissionregistration.Webhook, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj) // fuzz self without calling this function again
|
||||
p := admissionregistration.FailurePolicyType("Fail")
|
||||
obj.FailurePolicy = &p
|
||||
|
|
|
@ -35,7 +35,7 @@ func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *r
|
|||
if err := announced.NewGroupMetaFactory(
|
||||
&announced.GroupMetaFactoryArgs{
|
||||
GroupName: admissionregistration.GroupName,
|
||||
RootScopedKinds: sets.NewString("InitializerConfiguration", "ExternalAdmissionHookConfiguration"),
|
||||
RootScopedKinds: sets.NewString("InitializerConfiguration", "ValidatingWebhookConfiguration"),
|
||||
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
|
||||
AddInternalObjectsToScheme: admissionregistration.AddToScheme,
|
||||
},
|
||||
|
|
|
@ -46,8 +46,9 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
|||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&InitializerConfiguration{},
|
||||
&InitializerConfigurationList{},
|
||||
&ExternalAdmissionHookConfiguration{},
|
||||
&ExternalAdmissionHookConfigurationList{},
|
||||
&ValidatingWebhookConfiguration{},
|
||||
&ValidatingWebhookConfigurationList{},
|
||||
// TODO add mutating configs here too
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -118,35 +118,33 @@ const (
|
|||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ExternalAdmissionHookConfiguration describes the configuration of initializers.
|
||||
type ExternalAdmissionHookConfiguration struct {
|
||||
// ValidatingWebhookConfiguration describes the configuration of an admission webhook that accept or reject and object without changing it.
|
||||
type ValidatingWebhookConfiguration struct {
|
||||
metav1.TypeMeta
|
||||
// Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata.
|
||||
// +optional
|
||||
metav1.ObjectMeta
|
||||
// ExternalAdmissionHooks is a list of external admission webhooks and the
|
||||
// affected resources and operations.
|
||||
// Webhooks is a list of webhooks and the affected resources and operations.
|
||||
// +optional
|
||||
ExternalAdmissionHooks []ExternalAdmissionHook
|
||||
Webhooks []Webhook
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ExternalAdmissionHookConfigurationList is a list of ExternalAdmissionHookConfiguration.
|
||||
type ExternalAdmissionHookConfigurationList struct {
|
||||
// ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.
|
||||
type ValidatingWebhookConfigurationList struct {
|
||||
metav1.TypeMeta
|
||||
// Standard list metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
|
||||
// +optional
|
||||
metav1.ListMeta
|
||||
// List of ExternalAdmissionHookConfiguration.
|
||||
Items []ExternalAdmissionHookConfiguration
|
||||
// List of ValidatingWebhookConfiguration.
|
||||
Items []ValidatingWebhookConfiguration
|
||||
}
|
||||
|
||||
// ExternalAdmissionHook describes an external admission webhook and the
|
||||
// resources and operations it applies to.
|
||||
type ExternalAdmissionHook struct {
|
||||
// The name of the external admission webhook.
|
||||
// Webhook describes an admission webhook and the resources and operations it applies to.
|
||||
type Webhook struct {
|
||||
// The name of the admission webhook.
|
||||
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
|
||||
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
|
||||
// of the organization.
|
||||
|
@ -155,7 +153,7 @@ type ExternalAdmissionHook struct {
|
|||
|
||||
// ClientConfig defines how to communicate with the hook.
|
||||
// Required
|
||||
ClientConfig AdmissionHookClientConfig
|
||||
ClientConfig WebhookClientConfig
|
||||
|
||||
// Rules describes what operations on what resources/subresources the webhook cares about.
|
||||
// The webhook cares about an operation if it matches _any_ Rule.
|
||||
|
@ -191,9 +189,9 @@ const (
|
|||
Connect OperationType = "CONNECT"
|
||||
)
|
||||
|
||||
// AdmissionHookClientConfig contains the information to make a TLS
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
// connection with the webhook
|
||||
type AdmissionHookClientConfig struct {
|
||||
type WebhookClientConfig struct {
|
||||
// Service is a reference to the service for this webhook. If there is only
|
||||
// one port open for the service, that port will be used. If there are multiple
|
||||
// ports open, port 443 will be used if it is open, otherwise it is an error.
|
||||
|
|
|
@ -25,7 +25,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
|||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_ExternalAdmissionHook(obj *admissionregistrationv1alpha1.ExternalAdmissionHook) {
|
||||
func SetDefaults_Webhook(obj *admissionregistrationv1alpha1.Webhook) {
|
||||
if obj.FailurePolicy == nil {
|
||||
policy := admissionregistrationv1alpha1.Ignore
|
||||
obj.FailurePolicy = &policy
|
||||
|
|
|
@ -21,7 +21,7 @@ limitations under the License.
|
|||
|
||||
// Package v1alpha1 is the v1alpha1 version of the API.
|
||||
// AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration
|
||||
// admissionregistrationv1alpha1.InitializerConfiguration and admissionregistrationv1alpha1.ExternalAdmissionHookConfiguration is for the
|
||||
// admissionregistrationv1alpha1.InitializerConfiguration and admissionregistrationv1alpha1.ValidatingWebhookConfiguration is for the
|
||||
// new dynamic admission controller configuration.
|
||||
// +groupName=admissionregistration.k8s.io
|
||||
package v1alpha1 // import "k8s.io/kubernetes/pkg/apis/admissionregistration/v1alpha1"
|
||||
|
|
|
@ -163,15 +163,15 @@ func ValidateInitializerConfigurationUpdate(newIC, oldIC *admissionregistration.
|
|||
return ValidateInitializerConfiguration(newIC)
|
||||
}
|
||||
|
||||
func ValidateExternalAdmissionHookConfiguration(e *admissionregistration.ExternalAdmissionHookConfiguration) field.ErrorList {
|
||||
func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||
allErrors := genericvalidation.ValidateObjectMeta(&e.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
||||
for i, hook := range e.ExternalAdmissionHooks {
|
||||
allErrors = append(allErrors, validateExternalAdmissionHook(&hook, field.NewPath("externalAdmissionHooks").Index(i))...)
|
||||
for i, hook := range e.Webhooks {
|
||||
allErrors = append(allErrors, validateWebhook(&hook, field.NewPath("validatingWebhooks").Index(i))...)
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func validateExternalAdmissionHook(hook *admissionregistration.ExternalAdmissionHook, fldPath *field.Path) field.ErrorList {
|
||||
func validateWebhook(hook *admissionregistration.Webhook, fldPath *field.Path) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
// hook.Name must be fully qualified
|
||||
allErrors = append(allErrors, validation.IsFullyQualifiedName(fldPath.Child("name"), hook.Name)...)
|
||||
|
@ -263,6 +263,6 @@ func validateRuleWithOperations(ruleWithOperations *admissionregistration.RuleWi
|
|||
return allErrors
|
||||
}
|
||||
|
||||
func ValidateExternalAdmissionHookConfigurationUpdate(newC, oldC *admissionregistration.ExternalAdmissionHookConfiguration) field.ErrorList {
|
||||
return ValidateExternalAdmissionHookConfiguration(newC)
|
||||
func ValidateValidatingwebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||
return ValidateValidatingWebhookConfiguration(newC)
|
||||
}
|
||||
|
|
|
@ -231,25 +231,25 @@ func TestValidateInitializerConfiguration(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func getExternalAdmissionHookConfiguration(hooks []admissionregistration.ExternalAdmissionHook) *admissionregistration.ExternalAdmissionHookConfiguration {
|
||||
return &admissionregistration.ExternalAdmissionHookConfiguration{
|
||||
func getValidatingWebhookConfiguration(hooks []admissionregistration.Webhook) *admissionregistration.ValidatingWebhookConfiguration {
|
||||
return &admissionregistration.ValidatingWebhookConfiguration{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "config",
|
||||
},
|
||||
ExternalAdmissionHooks: hooks,
|
||||
Webhooks: hooks,
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
||||
func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config *admissionregistration.ExternalAdmissionHookConfiguration
|
||||
config *admissionregistration.ValidatingWebhookConfiguration
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "all ExternalAdmissionHook must have a fully qualified name",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
name: "all Webhooks must have a fully qualified name",
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
},
|
||||
|
@ -260,12 +260,12 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
Name: "",
|
||||
},
|
||||
}),
|
||||
expectedError: `externalAdmissionHooks[1].name: Invalid value: "k8s.io": should be a domain with at least three segments separated by dots, externalAdmissionHooks[2].name: Required value`,
|
||||
expectedError: `validatingWebhooks[1].name: Invalid value: "k8s.io": should be a domain with at least three segments separated by dots, validatingWebhooks[2].name: Required value`,
|
||||
},
|
||||
{
|
||||
name: "Operations must not be empty or nil",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -288,12 +288,12 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}),
|
||||
expectedError: `externalAdmissionHooks[0].rules[0].operations: Required value, externalAdmissionHooks[0].rules[1].operations: Required value`,
|
||||
expectedError: `validatingWebhooks[0].rules[0].operations: Required value, validatingWebhooks[0].rules[1].operations: Required value`,
|
||||
},
|
||||
{
|
||||
name: "\"\" is NOT a valid operation",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -312,8 +312,8 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "operation must be either create/update/delete/connect",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -332,8 +332,8 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "wildcard operation cannot be mixed with other strings",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -352,8 +352,8 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: `resource "*" can co-exist with resources that have subresources`,
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -371,8 +371,8 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: `resource "*" cannot mix with resources that don't have subresources`,
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -391,8 +391,8 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "resource a/* cannot mix with a/x",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -407,12 +407,12 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}),
|
||||
expectedError: `externalAdmissionHooks[0].rules[0].resources[1]: Invalid value: "a/x": if 'a/*' is present, must not specify a/x`,
|
||||
expectedError: `validatingWebhooks[0].rules[0].resources[1]: Invalid value: "a/x": if 'a/*' is present, must not specify a/x`,
|
||||
},
|
||||
{
|
||||
name: "resource a/* can mix with a",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -430,8 +430,8 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "resource */a cannot mix with x/a",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -446,12 +446,12 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}),
|
||||
expectedError: `externalAdmissionHooks[0].rules[0].resources[1]: Invalid value: "x/a": if '*/a' is present, must not specify x/a`,
|
||||
expectedError: `validatingWebhooks[0].rules[0].resources[1]: Invalid value: "x/a": if '*/a' is present, must not specify x/a`,
|
||||
},
|
||||
{
|
||||
name: "resource */* cannot mix with other resources",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -466,12 +466,12 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}),
|
||||
expectedError: `externalAdmissionHooks[0].rules[0].resources: Invalid value: []string{"*/*", "a"}: if '*/*' is present, must not specify other resources`,
|
||||
expectedError: `validatingWebhooks[0].rules[0].resources: Invalid value: []string{"*/*", "a"}: if '*/*' is present, must not specify other resources`,
|
||||
},
|
||||
{
|
||||
name: "FailurePolicy can only be \"Ignore\" or \"Fail\"",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
FailurePolicy: func() *admissionregistration.FailurePolicyType {
|
||||
|
@ -480,15 +480,15 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
}(),
|
||||
},
|
||||
}),
|
||||
expectedError: `externalAdmissionHooks[0].failurePolicy: Unsupported value: "other": supported values: "Fail", "Ignore"`,
|
||||
expectedError: `validatingWebhooks[0].failurePolicy: Unsupported value: "other": supported values: "Fail", "Ignore"`,
|
||||
},
|
||||
{
|
||||
name: "URLPath must start with slash",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.AdmissionHookClientConfig{
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URLPath: "foo/",
|
||||
},
|
||||
},
|
||||
|
@ -497,11 +497,11 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "URLPath accepts slash",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.AdmissionHookClientConfig{
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URLPath: "/",
|
||||
},
|
||||
},
|
||||
|
@ -510,11 +510,11 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "URLPath accepts no trailing slash",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.AdmissionHookClientConfig{
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URLPath: "/foo",
|
||||
},
|
||||
},
|
||||
|
@ -523,11 +523,11 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "URLPath fails //",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.AdmissionHookClientConfig{
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URLPath: "//",
|
||||
},
|
||||
},
|
||||
|
@ -536,11 +536,11 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "URLPath no empty step",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.AdmissionHookClientConfig{
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URLPath: "/foo//bar/",
|
||||
},
|
||||
},
|
||||
|
@ -548,11 +548,11 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
expectedError: `clientConfig.urlPath: Invalid value: "/foo//bar/": segment[1] may not be empty`,
|
||||
}, {
|
||||
name: "URLPath no empty step 2",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.AdmissionHookClientConfig{
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URLPath: "/foo/bar//",
|
||||
},
|
||||
},
|
||||
|
@ -561,11 +561,11 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "URLPath no non-subdomain",
|
||||
config: getExternalAdmissionHookConfiguration(
|
||||
[]admissionregistration.ExternalAdmissionHook{
|
||||
config: getValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.AdmissionHookClientConfig{
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URLPath: "/apis/foo.bar/v1alpha1/--bad",
|
||||
},
|
||||
},
|
||||
|
@ -575,7 +575,7 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
errs := ValidateExternalAdmissionHookConfiguration(test.config)
|
||||
errs := ValidateValidatingWebhookConfiguration(test.config)
|
||||
err := errs.ToAggregate()
|
||||
if err != nil {
|
||||
if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
|
||||
|
|
|
@ -106,7 +106,7 @@ func init() {
|
|||
if err := announced.NewGroupMetaFactory(
|
||||
&announced.GroupMetaFactoryArgs{
|
||||
GroupName: admissionregistrationv1alpha1.GroupName,
|
||||
RootScopedKinds: sets.NewString("InitializerConfiguration", "ExternalAdmissionHookConfiguration"),
|
||||
RootScopedKinds: sets.NewString("InitializerConfiguration", "ValidatingWebhookConfiguration"),
|
||||
VersionPreferenceOrder: []string{admissionregistrationv1alpha1.SchemeGroupVersion.Version},
|
||||
},
|
||||
announced.VersionToSchemeFunc{
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 externaladmissionhookconfiguration
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration/validation"
|
||||
)
|
||||
|
||||
// externaladmissionhookConfigurationStrategy implements verification logic for ExternalAdmissionHookConfiguration.
|
||||
type externaladmissionhookConfigurationStrategy struct {
|
||||
runtime.ObjectTyper
|
||||
names.NameGenerator
|
||||
}
|
||||
|
||||
// Strategy is the default logic that applies when creating and updating ExternalAdmissionHookConfiguration objects.
|
||||
var Strategy = externaladmissionhookConfigurationStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
|
||||
|
||||
// NamespaceScoped returns true because all ExternalAdmissionHookConfiguration' need to be within a namespace.
|
||||
func (externaladmissionhookConfigurationStrategy) NamespaceScoped() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// PrepareForCreate clears the status of an ExternalAdmissionHookConfiguration before creation.
|
||||
func (externaladmissionhookConfigurationStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
|
||||
ic := obj.(*admissionregistration.ExternalAdmissionHookConfiguration)
|
||||
ic.Generation = 1
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (externaladmissionhookConfigurationStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
|
||||
newIC := obj.(*admissionregistration.ExternalAdmissionHookConfiguration)
|
||||
oldIC := old.(*admissionregistration.ExternalAdmissionHookConfiguration)
|
||||
|
||||
// Any changes to the spec increment the generation number, any changes to the
|
||||
// status should reflect the generation number of the corresponding object.
|
||||
// See metav1.ObjectMeta description for more information on Generation.
|
||||
if !reflect.DeepEqual(oldIC.ExternalAdmissionHooks, newIC.ExternalAdmissionHooks) {
|
||||
newIC.Generation = oldIC.Generation + 1
|
||||
}
|
||||
}
|
||||
|
||||
// Validate validates a new ExternalAdmissionHookConfiguration.
|
||||
func (externaladmissionhookConfigurationStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList {
|
||||
ic := obj.(*admissionregistration.ExternalAdmissionHookConfiguration)
|
||||
return validation.ValidateExternalAdmissionHookConfiguration(ic)
|
||||
}
|
||||
|
||||
// Canonicalize normalizes the object after validation.
|
||||
func (externaladmissionhookConfigurationStrategy) Canonicalize(obj runtime.Object) {
|
||||
}
|
||||
|
||||
// AllowCreateOnUpdate is true for ExternalAdmissionHookConfiguration; this means you may create one with a PUT request.
|
||||
func (externaladmissionhookConfigurationStrategy) AllowCreateOnUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (externaladmissionhookConfigurationStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
|
||||
validationErrorList := validation.ValidateExternalAdmissionHookConfiguration(obj.(*admissionregistration.ExternalAdmissionHookConfiguration))
|
||||
updateErrorList := validation.ValidateExternalAdmissionHookConfigurationUpdate(obj.(*admissionregistration.ExternalAdmissionHookConfiguration), old.(*admissionregistration.ExternalAdmissionHookConfiguration))
|
||||
return append(validationErrorList, updateErrorList...)
|
||||
}
|
||||
|
||||
// AllowUnconditionalUpdate is the default update policy for ExternalAdmissionHookConfiguration objects. Status update should
|
||||
// only be allowed if version match.
|
||||
func (externaladmissionhookConfigurationStrategy) AllowUnconditionalUpdate() bool {
|
||||
return false
|
||||
}
|
|
@ -24,8 +24,8 @@ import (
|
|||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||
externaladmissionhookconfigurationstorage "k8s.io/kubernetes/pkg/registry/admissionregistration/externaladmissionhookconfiguration/storage"
|
||||
initializerconfigurationstorage "k8s.io/kubernetes/pkg/registry/admissionregistration/initializerconfiguration/storage"
|
||||
validatingwebhookconfigurationstorage "k8s.io/kubernetes/pkg/registry/admissionregistration/validatingwebhookconfiguration/storage"
|
||||
)
|
||||
|
||||
type RESTStorageProvider struct{}
|
||||
|
@ -49,9 +49,9 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstora
|
|||
s := initializerconfigurationstorage.NewREST(restOptionsGetter)
|
||||
storage["initializerconfigurations"] = s
|
||||
}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("externaladmissionhookconfigurations")) {
|
||||
s := externaladmissionhookconfigurationstorage.NewREST(restOptionsGetter)
|
||||
storage["externaladmissionhookconfigurations"] = s
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("validatingwebhookconfigurations")) {
|
||||
s := validatingwebhookconfigurationstorage.NewREST(restOptionsGetter)
|
||||
storage["validatingwebhookconfigurations"] = s
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
|
|
@ -14,4 +14,4 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package externaladmissionhookconfiguration // import "k8s.io/kubernetes/pkg/registry/admissionregistration/externaladmissionhookconfiguration"
|
||||
package validatingwebhookconfiguration // import "k8s.io/kubernetes/pkg/registry/admissionregistration/validatingwebhookconfiguration"
|
|
@ -21,7 +21,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||
"k8s.io/kubernetes/pkg/registry/admissionregistration/externaladmissionhookconfiguration"
|
||||
"k8s.io/kubernetes/pkg/registry/admissionregistration/validatingwebhookconfiguration"
|
||||
)
|
||||
|
||||
// rest implements a RESTStorage for pod disruption budgets against etcd
|
||||
|
@ -32,16 +32,16 @@ type REST struct {
|
|||
// NewREST returns a RESTStorage object that will work against pod disruption budgets.
|
||||
func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
|
||||
store := &genericregistry.Store{
|
||||
NewFunc: func() runtime.Object { return &admissionregistration.ExternalAdmissionHookConfiguration{} },
|
||||
NewListFunc: func() runtime.Object { return &admissionregistration.ExternalAdmissionHookConfigurationList{} },
|
||||
NewFunc: func() runtime.Object { return &admissionregistration.ValidatingWebhookConfiguration{} },
|
||||
NewListFunc: func() runtime.Object { return &admissionregistration.ValidatingWebhookConfigurationList{} },
|
||||
ObjectNameFunc: func(obj runtime.Object) (string, error) {
|
||||
return obj.(*admissionregistration.ExternalAdmissionHookConfiguration).Name, nil
|
||||
return obj.(*admissionregistration.ValidatingWebhookConfiguration).Name, nil
|
||||
},
|
||||
DefaultQualifiedResource: admissionregistration.Resource("externaladmissionhookconfigurations"),
|
||||
DefaultQualifiedResource: admissionregistration.Resource("validatingwebhookconfigurations"),
|
||||
|
||||
CreateStrategy: externaladmissionhookconfiguration.Strategy,
|
||||
UpdateStrategy: externaladmissionhookconfiguration.Strategy,
|
||||
DeleteStrategy: externaladmissionhookconfiguration.Strategy,
|
||||
CreateStrategy: validatingwebhookconfiguration.Strategy,
|
||||
UpdateStrategy: validatingwebhookconfiguration.Strategy,
|
||||
DeleteStrategy: validatingwebhookconfiguration.Strategy,
|
||||
}
|
||||
options := &generic.StoreOptions{RESTOptions: optsGetter}
|
||||
if err := store.CompleteWithOptions(options); err != nil {
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2014 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 validatingwebhookconfiguration
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration/validation"
|
||||
)
|
||||
|
||||
// validatingWebhookConfigurationStrategy implements verification logic for validatingWebhookConfiguration.
|
||||
type validatingWebhookConfigurationStrategy struct {
|
||||
runtime.ObjectTyper
|
||||
names.NameGenerator
|
||||
}
|
||||
|
||||
// Strategy is the default logic that applies when creating and updating validatingWebhookConfiguration objects.
|
||||
var Strategy = validatingWebhookConfigurationStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
|
||||
|
||||
// NamespaceScoped returns true because all validatingWebhookConfiguration' need to be within a namespace.
|
||||
func (validatingWebhookConfigurationStrategy) NamespaceScoped() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// PrepareForCreate clears the status of an validatingWebhookConfiguration before creation.
|
||||
func (validatingWebhookConfigurationStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
|
||||
ic := obj.(*admissionregistration.ValidatingWebhookConfiguration)
|
||||
ic.Generation = 1
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (validatingWebhookConfigurationStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
|
||||
newIC := obj.(*admissionregistration.ValidatingWebhookConfiguration)
|
||||
oldIC := old.(*admissionregistration.ValidatingWebhookConfiguration)
|
||||
|
||||
// Any changes to the spec increment the generation number, any changes to the
|
||||
// status should reflect the generation number of the corresponding object.
|
||||
// See metav1.ObjectMeta description for more information on Generation.
|
||||
if !reflect.DeepEqual(oldIC.Webhooks, newIC.Webhooks) {
|
||||
newIC.Generation = oldIC.Generation + 1
|
||||
}
|
||||
}
|
||||
|
||||
// Validate validates a new validatingWebhookConfiguration.
|
||||
func (validatingWebhookConfigurationStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList {
|
||||
ic := obj.(*admissionregistration.ValidatingWebhookConfiguration)
|
||||
return validation.ValidateValidatingWebhookConfiguration(ic)
|
||||
}
|
||||
|
||||
// Canonicalize normalizes the object after validation.
|
||||
func (validatingWebhookConfigurationStrategy) Canonicalize(obj runtime.Object) {
|
||||
}
|
||||
|
||||
// AllowCreateOnUpdate is true for validatingWebhookConfiguration; this means you may create one with a PUT request.
|
||||
func (validatingWebhookConfigurationStrategy) AllowCreateOnUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (validatingWebhookConfigurationStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
|
||||
validationErrorList := validation.ValidateValidatingWebhookConfiguration(obj.(*admissionregistration.ValidatingWebhookConfiguration))
|
||||
updateErrorList := validation.ValidateValidatingwebhookConfigurationUpdate(obj.(*admissionregistration.ValidatingWebhookConfiguration), old.(*admissionregistration.ValidatingWebhookConfiguration))
|
||||
return append(validationErrorList, updateErrorList...)
|
||||
}
|
||||
|
||||
// AllowUnconditionalUpdate is the default update policy for validatingWebhookConfiguration objects. Status update should
|
||||
// only be allowed if version match.
|
||||
func (validatingWebhookConfigurationStrategy) AllowUnconditionalUpdate() bool {
|
||||
return false
|
||||
}
|
|
@ -19,7 +19,7 @@ limitations under the License.
|
|||
|
||||
// Package v1alpha1 is the v1alpha1 version of the API.
|
||||
// AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration
|
||||
// InitializerConfiguration and ExternalAdmissionHookConfiguration is for the
|
||||
// InitializerConfiguration and validatingWebhookConfiguration is for the
|
||||
// new dynamic admission controller configuration.
|
||||
// +groupName=admissionregistration.k8s.io
|
||||
package v1alpha1 // import "k8s.io/api/admissionregistration/v1alpha1"
|
||||
|
|
|
@ -45,8 +45,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
|||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&InitializerConfiguration{},
|
||||
&InitializerConfigurationList{},
|
||||
&ExternalAdmissionHookConfiguration{},
|
||||
&ExternalAdmissionHookConfigurationList{},
|
||||
&ValidatingWebhookConfiguration{},
|
||||
&ValidatingWebhookConfigurationList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
|
|
@ -120,37 +120,35 @@ const (
|
|||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ExternalAdmissionHookConfiguration describes the configuration of initializers.
|
||||
type ExternalAdmissionHookConfiguration struct {
|
||||
// ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.
|
||||
type ValidatingWebhookConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata.
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
// ExternalAdmissionHooks is a list of external admission webhooks and the
|
||||
// affected resources and operations.
|
||||
// Webhooks is a list of webhooks and the affected resources and operations.
|
||||
// +optional
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
ExternalAdmissionHooks []ExternalAdmissionHook `json:"externalAdmissionHooks,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,2,rep,name=externalAdmissionHooks"`
|
||||
Webhooks []Webhook `json:"Webhooks,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,2,rep,name=Webhooks"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ExternalAdmissionHookConfigurationList is a list of ExternalAdmissionHookConfiguration.
|
||||
type ExternalAdmissionHookConfigurationList struct {
|
||||
// ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.
|
||||
type ValidatingWebhookConfigurationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
// List of ExternalAdmissionHookConfiguration.
|
||||
Items []ExternalAdmissionHookConfiguration `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
// List of ValidatingWebhookConfiguration.
|
||||
Items []ValidatingWebhookConfiguration `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
// ExternalAdmissionHook describes an external admission webhook and the
|
||||
// resources and operations it applies to.
|
||||
type ExternalAdmissionHook struct {
|
||||
// The name of the external admission webhook.
|
||||
// Webhook describes an admission webhook and the resources and operations it applies to.
|
||||
type Webhook struct {
|
||||
// The name of the admission webhook.
|
||||
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
|
||||
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
|
||||
// of the organization.
|
||||
|
@ -159,7 +157,7 @@ type ExternalAdmissionHook struct {
|
|||
|
||||
// ClientConfig defines how to communicate with the hook.
|
||||
// Required
|
||||
ClientConfig AdmissionHookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"`
|
||||
ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"`
|
||||
|
||||
// Rules describes what operations on what resources/subresources the webhook cares about.
|
||||
// The webhook cares about an operation if it matches _any_ Rule.
|
||||
|
@ -195,9 +193,9 @@ const (
|
|||
Connect OperationType = "CONNECT"
|
||||
)
|
||||
|
||||
// AdmissionHookClientConfig contains the information to make a TLS
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
// connection with the webhook
|
||||
type AdmissionHookClientConfig struct {
|
||||
type WebhookClientConfig struct {
|
||||
// Service is a reference to the service for this webhook. If there is only
|
||||
// one port open for the service, that port will be used. If there are multiple
|
||||
// ports open, port 443 will be used if it is open, otherwise it is an error.
|
||||
|
|
|
@ -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,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,
|
||||
|
|
|
@ -56,7 +56,7 @@ var _ = SIGDescribe("AdmissionWebhook", func() {
|
|||
framework.SkipUnlessServerVersionGTE(serverWebhookVersion, f.ClientSet.Discovery())
|
||||
framework.SkipUnlessProviderIs("gce", "gke")
|
||||
|
||||
_, err := f.ClientSet.AdmissionregistrationV1alpha1().ExternalAdmissionHookConfigurations().List(metav1.ListOptions{})
|
||||
_, err := f.ClientSet.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().List(metav1.ListOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
framework.Skipf("dynamic configuration of webhooks requires the alpha admissionregistration.k8s.io group to be enabled")
|
||||
}
|
||||
|
@ -217,11 +217,11 @@ func registerWebhook(f *framework.Framework, context *certContext) {
|
|||
By("Registering the webhook via the AdmissionRegistration API")
|
||||
|
||||
namespace := f.Namespace.Name
|
||||
_, err := client.AdmissionregistrationV1alpha1().ExternalAdmissionHookConfigurations().Create(&v1alpha1.ExternalAdmissionHookConfiguration{
|
||||
_, err := client.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().Create(&v1alpha1.ValidatingWebhookConfiguration{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: webhookConfigName,
|
||||
},
|
||||
ExternalAdmissionHooks: []v1alpha1.ExternalAdmissionHook{
|
||||
Webhooks: []v1alpha1.Webhook{
|
||||
{
|
||||
Name: "e2e-test-webhook.k8s.io",
|
||||
Rules: []v1alpha1.RuleWithOperations{{
|
||||
|
@ -232,7 +232,7 @@ func registerWebhook(f *framework.Framework, context *certContext) {
|
|||
Resources: []string{"pods"},
|
||||
},
|
||||
}},
|
||||
ClientConfig: v1alpha1.AdmissionHookClientConfig{
|
||||
ClientConfig: v1alpha1.WebhookClientConfig{
|
||||
Service: v1alpha1.ServiceReference{
|
||||
Namespace: namespace,
|
||||
Name: serviceName,
|
||||
|
@ -285,7 +285,7 @@ func nonCompliantPod(f *framework.Framework) *v1.Pod {
|
|||
|
||||
func cleanWebhookTest(f *framework.Framework) {
|
||||
client := f.ClientSet
|
||||
_ = client.AdmissionregistrationV1alpha1().ExternalAdmissionHookConfigurations().Delete(webhookConfigName, nil)
|
||||
_ = client.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().Delete(webhookConfigName, nil)
|
||||
namespaceName := f.Namespace.Name
|
||||
_ = client.CoreV1().Services(namespaceName).Delete(serviceName, nil)
|
||||
_ = client.ExtensionsV1beta1().Deployments(namespaceName).Delete(deploymentName, nil)
|
||||
|
|
|
@ -381,9 +381,9 @@ var etcdStorageData = map[schema.GroupVersionResource]struct {
|
|||
stub: `{"metadata":{"name":"ic1"},"initializers":[{"name":"initializer.k8s.io","rules":[{"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`,
|
||||
expectedEtcdPath: "/registry/initializerconfigurations/ic1",
|
||||
},
|
||||
gvr("admissionregistration.k8s.io", "v1alpha1", "externaladmissionhookconfigurations"): {
|
||||
stub: `{"metadata":{"name":"hook1","creationTimestamp":null},"externalAdmissionHooks":[{"name":"externaladmissionhook.k8s.io","clientConfig":{"service":{"namespace":"","name":""},"caBundle":null},"rules":[{"operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`,
|
||||
expectedEtcdPath: "/registry/externaladmissionhookconfigurations/hook1",
|
||||
gvr("admissionregistration.k8s.io", "v1alpha1", "validatingwebhookconfigurations"): {
|
||||
stub: `{"metadata":{"name":"hook1","creationTimestamp":null},"webhooks":[{"name":"externaladmissionhook.k8s.io","clientConfig":{"service":{"namespace":"","name":""},"caBundle":null},"rules":[{"operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`,
|
||||
expectedEtcdPath: "/registry/validatingwebhookconfigurations/hook1",
|
||||
},
|
||||
// --
|
||||
|
||||
|
|
Loading…
Reference in New Issue