mirror of https://github.com/k3s-io/k3s
Add AdmissionReviewVersions to admissionregistration and default it
parent
9eebfe7a04
commit
f7dff4725f
|
@ -43,6 +43,7 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||||
i := int32(30)
|
i := int32(30)
|
||||||
obj.TimeoutSeconds = &i
|
obj.TimeoutSeconds = &i
|
||||||
}
|
}
|
||||||
|
obj.AdmissionReviewVersions = []string{"v1beta1"}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,6 +239,15 @@ type Webhook struct {
|
||||||
// The timeout value must be between 1 and 30 seconds.
|
// The timeout value must be between 1 and 30 seconds.
|
||||||
// +optional
|
// +optional
|
||||||
TimeoutSeconds *int32
|
TimeoutSeconds *int32
|
||||||
|
|
||||||
|
// AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
|
||||||
|
// versions the Webhook expects. API server will try to use first version in
|
||||||
|
// the list which it supports. If none of the versions specified in this list
|
||||||
|
// supported by API server, validation will fail for this object.
|
||||||
|
// If the webhook configuration has already been persisted with a version apiserver
|
||||||
|
// does not understand, calls to the webhook will fail and be subject to the failure policy.
|
||||||
|
// +optional
|
||||||
|
AdmissionReviewVersions []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
|
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
|
||||||
|
|
|
@ -44,6 +44,10 @@ func SetDefaults_Webhook(obj *admissionregistrationv1beta1.Webhook) {
|
||||||
obj.TimeoutSeconds = new(int32)
|
obj.TimeoutSeconds = new(int32)
|
||||||
*obj.TimeoutSeconds = 30
|
*obj.TimeoutSeconds = 30
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(obj.AdmissionReviewVersions) == 0 {
|
||||||
|
obj.AdmissionReviewVersions = []string{admissionregistrationv1beta1.SchemeGroupVersion.Version}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetDefaults_Rule(obj *admissionregistrationv1beta1.Rule) {
|
func SetDefaults_Rule(obj *admissionregistrationv1beta1.Rule) {
|
||||||
|
|
|
@ -24,9 +24,11 @@ import (
|
||||||
metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/apiserver/pkg/util/webhook"
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/admissionregistration/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func hasWildcard(slice []string) bool {
|
func hasWildcard(slice []string) bool {
|
||||||
|
@ -150,18 +152,71 @@ func validateRule(rule *admissionregistration.Rule, fldPath *field.Path, allowSu
|
||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AcceptedAdmissionReviewVersions = []string{v1beta1.SchemeGroupVersion.Version}
|
||||||
|
|
||||||
|
func isAcceptedAdmissionReviewVersion(v string) bool {
|
||||||
|
for _, version := range AcceptedAdmissionReviewVersions {
|
||||||
|
if v == version {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateAdmissionReviewVersions(versions []string, requireRecognizedVersion bool, fldPath *field.Path) field.ErrorList {
|
||||||
|
allErrors := field.ErrorList{}
|
||||||
|
|
||||||
|
// Currently only v1beta1 accepted in AdmissionReviewVersions
|
||||||
|
if len(versions) < 1 {
|
||||||
|
allErrors = append(allErrors, field.Required(fldPath, ""))
|
||||||
|
} else {
|
||||||
|
seen := map[string]bool{}
|
||||||
|
hasAcceptedVersion := false
|
||||||
|
for i, v := range versions {
|
||||||
|
if seen[v] {
|
||||||
|
allErrors = append(allErrors, field.Invalid(fldPath.Index(i), v, "duplicate version"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[v] = true
|
||||||
|
for _, errString := range utilvalidation.IsDNS1035Label(v) {
|
||||||
|
allErrors = append(allErrors, field.Invalid(fldPath.Index(i), v, errString))
|
||||||
|
}
|
||||||
|
if isAcceptedAdmissionReviewVersion(v) {
|
||||||
|
hasAcceptedVersion = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if requireRecognizedVersion && !hasAcceptedVersion {
|
||||||
|
allErrors = append(allErrors, field.Invalid(
|
||||||
|
fldPath, versions,
|
||||||
|
fmt.Sprintf("none of the versions accepted by this server. accepted version(s) are %v",
|
||||||
|
strings.Join(AcceptedAdmissionReviewVersions, ", "))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allErrors
|
||||||
|
}
|
||||||
|
|
||||||
func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||||
|
return validateValidatingWebhookConfiguration(e, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration, requireRecognizedVersion bool) field.ErrorList {
|
||||||
allErrors := genericvalidation.ValidateObjectMeta(&e.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
allErrors := genericvalidation.ValidateObjectMeta(&e.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
||||||
for i, hook := range e.Webhooks {
|
for i, hook := range e.Webhooks {
|
||||||
allErrors = append(allErrors, validateWebhook(&hook, field.NewPath("webhooks").Index(i))...)
|
allErrors = append(allErrors, validateWebhook(&hook, field.NewPath("webhooks").Index(i))...)
|
||||||
|
allErrors = append(allErrors, validateAdmissionReviewVersions(hook.AdmissionReviewVersions, requireRecognizedVersion, field.NewPath("webhooks").Index(i).Child("admissionReviewVersions"))...)
|
||||||
}
|
}
|
||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
||||||
|
return validateMutatingWebhookConfiguration(e, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration, requireRecognizedVersion bool) field.ErrorList {
|
||||||
allErrors := genericvalidation.ValidateObjectMeta(&e.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
allErrors := genericvalidation.ValidateObjectMeta(&e.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
||||||
for i, hook := range e.Webhooks {
|
for i, hook := range e.Webhooks {
|
||||||
allErrors = append(allErrors, validateWebhook(&hook, field.NewPath("webhooks").Index(i))...)
|
allErrors = append(allErrors, validateWebhook(&hook, field.NewPath("webhooks").Index(i))...)
|
||||||
|
allErrors = append(allErrors, validateAdmissionReviewVersions(hook.AdmissionReviewVersions, requireRecognizedVersion, field.NewPath("webhooks").Index(i).Child("admissionReviewVersions"))...)
|
||||||
}
|
}
|
||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
@ -247,10 +302,28 @@ func validateRuleWithOperations(ruleWithOperations *admissionregistration.RuleWi
|
||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hasAcceptedAdmissionReviewVersions returns true if all webhooks have at least one
|
||||||
|
// admission review version this apiserver accepts.
|
||||||
|
func hasAcceptedAdmissionReviewVersions(webhooks []admissionregistration.Webhook) bool {
|
||||||
|
for _, hook := range webhooks {
|
||||||
|
hasRecognizedVersion := false
|
||||||
|
for _, version := range hook.AdmissionReviewVersions {
|
||||||
|
if isAcceptedAdmissionReviewVersion(version) {
|
||||||
|
hasRecognizedVersion = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasRecognizedVersion && len(hook.AdmissionReviewVersions) > 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||||
return ValidateValidatingWebhookConfiguration(newC)
|
return validateValidatingWebhookConfiguration(newC, hasAcceptedAdmissionReviewVersions(oldC.Webhooks))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateMutatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
func ValidateMutatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
||||||
return ValidateMutatingWebhookConfiguration(newC)
|
return validateMutatingWebhookConfiguration(newC, hasAcceptedAdmissionReviewVersions(oldC.Webhooks))
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -78,9 +78,7 @@ func (mutatingWebhookConfigurationStrategy) AllowCreateOnUpdate() bool {
|
||||||
|
|
||||||
// ValidateUpdate is the default update validation for an end user.
|
// ValidateUpdate is the default update validation for an end user.
|
||||||
func (mutatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
func (mutatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||||
validationErrorList := validation.ValidateMutatingWebhookConfiguration(obj.(*admissionregistration.MutatingWebhookConfiguration))
|
return validation.ValidateMutatingWebhookConfigurationUpdate(obj.(*admissionregistration.MutatingWebhookConfiguration), old.(*admissionregistration.MutatingWebhookConfiguration))
|
||||||
updateErrorList := validation.ValidateMutatingWebhookConfigurationUpdate(obj.(*admissionregistration.MutatingWebhookConfiguration), old.(*admissionregistration.MutatingWebhookConfiguration))
|
|
||||||
return append(validationErrorList, updateErrorList...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllowUnconditionalUpdate is the default update policy for mutatingWebhookConfiguration objects. Status update should
|
// AllowUnconditionalUpdate is the default update policy for mutatingWebhookConfiguration objects. Status update should
|
||||||
|
|
|
@ -63,8 +63,7 @@ func (validatingWebhookConfigurationStrategy) PrepareForUpdate(ctx context.Conte
|
||||||
|
|
||||||
// Validate validates a new validatingWebhookConfiguration.
|
// Validate validates a new validatingWebhookConfiguration.
|
||||||
func (validatingWebhookConfigurationStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
func (validatingWebhookConfigurationStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||||
ic := obj.(*admissionregistration.ValidatingWebhookConfiguration)
|
return validation.ValidateValidatingWebhookConfiguration(obj.(*admissionregistration.ValidatingWebhookConfiguration))
|
||||||
return validation.ValidateValidatingWebhookConfiguration(ic)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Canonicalize normalizes the object after validation.
|
// Canonicalize normalizes the object after validation.
|
||||||
|
@ -78,9 +77,7 @@ func (validatingWebhookConfigurationStrategy) AllowCreateOnUpdate() bool {
|
||||||
|
|
||||||
// ValidateUpdate is the default update validation for an end user.
|
// ValidateUpdate is the default update validation for an end user.
|
||||||
func (validatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
func (validatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||||
validationErrorList := validation.ValidateValidatingWebhookConfiguration(obj.(*admissionregistration.ValidatingWebhookConfiguration))
|
return validation.ValidateValidatingWebhookConfigurationUpdate(obj.(*admissionregistration.ValidatingWebhookConfiguration), old.(*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
|
// AllowUnconditionalUpdate is the default update policy for validatingWebhookConfiguration objects. Status update should
|
||||||
|
|
|
@ -248,6 +248,17 @@ type Webhook struct {
|
||||||
// Default to 30 seconds.
|
// Default to 30 seconds.
|
||||||
// +optional
|
// +optional
|
||||||
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"`
|
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"`
|
||||||
|
|
||||||
|
// AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
|
||||||
|
// versions the Webhook expects. API server will try to use first version in
|
||||||
|
// the list which it supports. If none of the versions specified in this list
|
||||||
|
// supported by API server, validation will fail for this object.
|
||||||
|
// If a persisted webhook configuration specifies allowed versions and does not
|
||||||
|
// include any versions known to the API Server, calls to the webhook will fail
|
||||||
|
// and be subject to the failure policy.
|
||||||
|
// Default to `['v1beta1']`.
|
||||||
|
// +optional
|
||||||
|
AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty" protobuf:"bytes,8,rep,name=admissionReviewVersions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
|
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
|
||||||
|
|
|
@ -94,6 +94,12 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Currently dispatcher only supports `v1beta1` AdmissionReview
|
||||||
|
// TODO: Make the dispatcher capable of sending multiple AdmissionReview versions
|
||||||
|
if !util.HasAdmissionReviewVersion(v1beta1.SchemeGroupVersion.Version, h) {
|
||||||
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("webhook does not accept v1beta1 AdmissionReview")}
|
||||||
|
}
|
||||||
|
|
||||||
// Make the webhook request
|
// Make the webhook request
|
||||||
request := request.CreateAdmissionReview(attr)
|
request := request.CreateAdmissionReview(attr)
|
||||||
client, err := a.cm.HookClient(util.HookClientConfigForWebhook(h))
|
client, err := a.cm.HookClient(util.HookClientConfigForWebhook(h))
|
||||||
|
|
|
@ -211,17 +211,19 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
Rules: []registrationv1beta1.RuleWithOperations{{
|
Rules: []registrationv1beta1.RuleWithOperations{{
|
||||||
Operations: []registrationv1beta1.OperationType{registrationv1beta1.Create},
|
Operations: []registrationv1beta1.OperationType{registrationv1beta1.Create},
|
||||||
}},
|
}},
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "match & allow",
|
Name: "match & allow",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "allow.example.com",
|
Name: "allow.example.com",
|
||||||
ClientConfig: ccfgSVC("allow"),
|
ClientConfig: ccfgSVC("allow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
|
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
|
||||||
|
@ -229,20 +231,22 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match & disallow",
|
Name: "match & disallow",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "disallow",
|
Name: "disallow",
|
||||||
ClientConfig: ccfgSVC("disallow"),
|
ClientConfig: ccfgSVC("disallow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ErrorContains: "without explanation",
|
ErrorContains: "without explanation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "match & disallow ii",
|
Name: "match & disallow ii",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "disallowReason",
|
Name: "disallowReason",
|
||||||
ClientConfig: ccfgSVC("disallowReason"),
|
ClientConfig: ccfgSVC("disallowReason"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
|
|
||||||
ErrorContains: "you shall not pass",
|
ErrorContains: "you shall not pass",
|
||||||
|
@ -260,6 +264,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
Operator: metav1.LabelSelectorOpIn,
|
Operator: metav1.LabelSelectorOpIn,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
|
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
|
@ -277,29 +282,33 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
Operator: metav1.LabelSelectorOpNotIn,
|
Operator: metav1.LabelSelectorOpNotIn,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "match & fail (but allow because fail open)",
|
Name: "match & fail (but allow because fail open)",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "internalErr A",
|
Name: "internalErr A",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}, {
|
}, {
|
||||||
Name: "internalErr B",
|
Name: "internalErr B",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}, {
|
}, {
|
||||||
Name: "internalErr C",
|
Name: "internalErr C",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
|
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
|
@ -307,53 +316,60 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match & fail (but disallow because fail close on nil FailurePolicy)",
|
Name: "match & fail (but disallow because fail close on nil FailurePolicy)",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "internalErr A",
|
Name: "internalErr A",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}, {
|
}, {
|
||||||
Name: "internalErr B",
|
Name: "internalErr B",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}, {
|
}, {
|
||||||
Name: "internalErr C",
|
Name: "internalErr C",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: false,
|
ExpectAllow: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "match & fail (but fail because fail closed)",
|
Name: "match & fail (but fail because fail closed)",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "internalErr A",
|
Name: "internalErr A",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyFail,
|
FailurePolicy: &policyFail,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}, {
|
}, {
|
||||||
Name: "internalErr B",
|
Name: "internalErr B",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyFail,
|
FailurePolicy: &policyFail,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}, {
|
}, {
|
||||||
Name: "internalErr C",
|
Name: "internalErr C",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyFail,
|
FailurePolicy: &policyFail,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: false,
|
ExpectAllow: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "match & allow (url)",
|
Name: "match & allow (url)",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "allow.example.com",
|
Name: "allow.example.com",
|
||||||
ClientConfig: ccfgURL("allow"),
|
ClientConfig: ccfgURL("allow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
|
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
|
||||||
|
@ -361,31 +377,34 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match & disallow (url)",
|
Name: "match & disallow (url)",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "disallow",
|
Name: "disallow",
|
||||||
ClientConfig: ccfgURL("disallow"),
|
ClientConfig: ccfgURL("disallow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ErrorContains: "without explanation",
|
ErrorContains: "without explanation",
|
||||||
}, {
|
}, {
|
||||||
Name: "absent response and fail open",
|
Name: "absent response and fail open",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "nilResponse",
|
Name: "nilResponse",
|
||||||
ClientConfig: ccfgURL("nilResponse"),
|
ClientConfig: ccfgURL("nilResponse"),
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "absent response and fail closed",
|
Name: "absent response and fail closed",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "nilResponse",
|
Name: "nilResponse",
|
||||||
ClientConfig: ccfgURL("nilResponse"),
|
ClientConfig: ccfgURL("nilResponse"),
|
||||||
FailurePolicy: &policyFail,
|
FailurePolicy: &policyFail,
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ErrorContains: "Webhook response was absent",
|
ErrorContains: "Webhook response was absent",
|
||||||
},
|
},
|
||||||
|
@ -397,8 +416,9 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
Rules: []registrationv1beta1.RuleWithOperations{{
|
Rules: []registrationv1beta1.RuleWithOperations{{
|
||||||
Operations: []registrationv1beta1.OperationType{registrationv1beta1.Create},
|
Operations: []registrationv1beta1.OperationType{registrationv1beta1.Create},
|
||||||
}},
|
}},
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
SideEffects: &sideEffectsSome,
|
SideEffects: &sideEffectsSome,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsDryRun: true,
|
IsDryRun: true,
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
|
@ -406,11 +426,12 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match dry run side effects Unknown",
|
Name: "match dry run side effects Unknown",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "allow",
|
Name: "allow",
|
||||||
ClientConfig: ccfgSVC("allow"),
|
ClientConfig: ccfgSVC("allow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
SideEffects: &sideEffectsUnknown,
|
SideEffects: &sideEffectsUnknown,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsDryRun: true,
|
IsDryRun: true,
|
||||||
ErrorContains: "does not support dry run",
|
ErrorContains: "does not support dry run",
|
||||||
|
@ -418,11 +439,12 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match dry run side effects None",
|
Name: "match dry run side effects None",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "allow",
|
Name: "allow",
|
||||||
ClientConfig: ccfgSVC("allow"),
|
ClientConfig: ccfgSVC("allow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
SideEffects: &sideEffectsNone,
|
SideEffects: &sideEffectsNone,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsDryRun: true,
|
IsDryRun: true,
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
|
@ -431,11 +453,12 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match dry run side effects Some",
|
Name: "match dry run side effects Some",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "allow",
|
Name: "allow",
|
||||||
ClientConfig: ccfgSVC("allow"),
|
ClientConfig: ccfgSVC("allow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
SideEffects: &sideEffectsSome,
|
SideEffects: &sideEffectsSome,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsDryRun: true,
|
IsDryRun: true,
|
||||||
ErrorContains: "does not support dry run",
|
ErrorContains: "does not support dry run",
|
||||||
|
@ -443,11 +466,12 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match dry run side effects NoneOnDryRun",
|
Name: "match dry run side effects NoneOnDryRun",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "allow",
|
Name: "allow",
|
||||||
ClientConfig: ccfgSVC("allow"),
|
ClientConfig: ccfgSVC("allow"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
SideEffects: &sideEffectsNoneOnDryRun,
|
SideEffects: &sideEffectsNoneOnDryRun,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsDryRun: true,
|
IsDryRun: true,
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
|
@ -456,10 +480,11 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "illegal annotation format",
|
Name: "illegal annotation format",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "invalidAnnotation",
|
Name: "invalidAnnotation",
|
||||||
ClientConfig: ccfgURL("invalidAnnotation"),
|
ClientConfig: ccfgURL("invalidAnnotation"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
},
|
},
|
||||||
|
@ -476,10 +501,11 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match & remove label",
|
Name: "match & remove label",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "removelabel.example.com",
|
Name: "removelabel.example.com",
|
||||||
ClientConfig: ccfgSVC("removeLabel"),
|
ClientConfig: ccfgSVC("removeLabel"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
AdditionalLabels: map[string]string{"remove": "me"},
|
AdditionalLabels: map[string]string{"remove": "me"},
|
||||||
|
@ -489,10 +515,11 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match & add label",
|
Name: "match & add label",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "addLabel",
|
Name: "addLabel",
|
||||||
ClientConfig: ccfgSVC("addLabel"),
|
ClientConfig: ccfgSVC("addLabel"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectLabels: map[string]string{"pod.name": "my-pod", "added": "test"},
|
ExpectLabels: map[string]string{"pod.name": "my-pod", "added": "test"},
|
||||||
|
@ -500,10 +527,11 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match CRD & add label",
|
Name: "match CRD & add label",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "addLabel",
|
Name: "addLabel",
|
||||||
ClientConfig: ccfgSVC("addLabel"),
|
ClientConfig: ccfgSVC("addLabel"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsCRD: true,
|
IsCRD: true,
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
|
@ -512,10 +540,11 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match CRD & remove label",
|
Name: "match CRD & remove label",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "removelabel.example.com",
|
Name: "removelabel.example.com",
|
||||||
ClientConfig: ccfgSVC("removeLabel"),
|
ClientConfig: ccfgSVC("removeLabel"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsCRD: true,
|
IsCRD: true,
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
|
@ -526,21 +555,23 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
||||||
{
|
{
|
||||||
Name: "match & invalid mutation",
|
Name: "match & invalid mutation",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "invalidMutation",
|
Name: "invalidMutation",
|
||||||
ClientConfig: ccfgSVC("invalidMutation"),
|
ClientConfig: ccfgSVC("invalidMutation"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ErrorContains: "invalid character",
|
ErrorContains: "invalid character",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "match & remove label dry run unsupported",
|
Name: "match & remove label dry run unsupported",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "removeLabel",
|
Name: "removeLabel",
|
||||||
ClientConfig: ccfgSVC("removeLabel"),
|
ClientConfig: ccfgSVC("removeLabel"),
|
||||||
Rules: matchEverythingRules,
|
Rules: matchEverythingRules,
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
SideEffects: &sideEffectsUnknown,
|
SideEffects: &sideEffectsUnknown,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
IsDryRun: true,
|
IsDryRun: true,
|
||||||
ErrorContains: "does not support dry run",
|
ErrorContains: "does not support dry run",
|
||||||
|
@ -567,11 +598,12 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
||||||
{
|
{
|
||||||
Name: "uncached: service webhook, path 'allow'",
|
Name: "uncached: service webhook, path 'allow'",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "cache1",
|
Name: "cache1",
|
||||||
ClientConfig: ccfgSVC("allow"),
|
ClientConfig: ccfgSVC("allow"),
|
||||||
Rules: newMatchEverythingRules(),
|
Rules: newMatchEverythingRules(),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectCacheMiss: true,
|
ExpectCacheMiss: true,
|
||||||
|
@ -579,11 +611,12 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
||||||
{
|
{
|
||||||
Name: "uncached: service webhook, path 'internalErr'",
|
Name: "uncached: service webhook, path 'internalErr'",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "cache2",
|
Name: "cache2",
|
||||||
ClientConfig: ccfgSVC("internalErr"),
|
ClientConfig: ccfgSVC("internalErr"),
|
||||||
Rules: newMatchEverythingRules(),
|
Rules: newMatchEverythingRules(),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectCacheMiss: true,
|
ExpectCacheMiss: true,
|
||||||
|
@ -591,11 +624,12 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
||||||
{
|
{
|
||||||
Name: "cached: service webhook, path 'allow'",
|
Name: "cached: service webhook, path 'allow'",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "cache3",
|
Name: "cache3",
|
||||||
ClientConfig: ccfgSVC("allow"),
|
ClientConfig: ccfgSVC("allow"),
|
||||||
Rules: newMatchEverythingRules(),
|
Rules: newMatchEverythingRules(),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectCacheMiss: false,
|
ExpectCacheMiss: false,
|
||||||
|
@ -603,11 +637,12 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
||||||
{
|
{
|
||||||
Name: "uncached: url webhook, path 'allow'",
|
Name: "uncached: url webhook, path 'allow'",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "cache4",
|
Name: "cache4",
|
||||||
ClientConfig: ccfgURL("allow"),
|
ClientConfig: ccfgURL("allow"),
|
||||||
Rules: newMatchEverythingRules(),
|
Rules: newMatchEverythingRules(),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectCacheMiss: true,
|
ExpectCacheMiss: true,
|
||||||
|
@ -615,11 +650,12 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
||||||
{
|
{
|
||||||
Name: "cached: service webhook, path 'allow'",
|
Name: "cached: service webhook, path 'allow'",
|
||||||
Webhooks: []registrationv1beta1.Webhook{{
|
Webhooks: []registrationv1beta1.Webhook{{
|
||||||
Name: "cache5",
|
Name: "cache5",
|
||||||
ClientConfig: ccfgURL("allow"),
|
ClientConfig: ccfgURL("allow"),
|
||||||
Rules: newMatchEverythingRules(),
|
Rules: newMatchEverythingRules(),
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
FailurePolicy: &policyIgnore,
|
FailurePolicy: &policyIgnore,
|
||||||
|
AdmissionReviewVersions: []string{"v1beta1"},
|
||||||
}},
|
}},
|
||||||
ExpectAllow: true,
|
ExpectAllow: true,
|
||||||
ExpectCacheMiss: false,
|
ExpectCacheMiss: false,
|
||||||
|
|
|
@ -40,3 +40,13 @@ func HookClientConfigForWebhook(w *v1beta1.Webhook) webhook.ClientConfig {
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasAdmissionReviewVersion check whether a version is accepted by a given webhook.
|
||||||
|
func HasAdmissionReviewVersion(a string, w *v1beta1.Webhook) bool {
|
||||||
|
for _, b := range w.AdmissionReviewVersions {
|
||||||
|
if b == a {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -108,6 +108,12 @@ func (d *validatingDispatcher) callHook(ctx context.Context, h *v1beta1.Webhook,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Currently dispatcher only supports `v1beta1` AdmissionReview
|
||||||
|
// TODO: Make the dispatcher capable of sending multiple AdmissionReview versions
|
||||||
|
if !util.HasAdmissionReviewVersion(v1beta1.SchemeGroupVersion.Version, h) {
|
||||||
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("webhook does not accept v1beta1 AdmissionReviewRequest")}
|
||||||
|
}
|
||||||
|
|
||||||
// Make the webhook request
|
// Make the webhook request
|
||||||
request := request.CreateAdmissionReview(attr)
|
request := request.CreateAdmissionReview(attr)
|
||||||
client, err := d.cm.HookClient(util.HookClientConfigForWebhook(h))
|
client, err := d.cm.HookClient(util.HookClientConfigForWebhook(h))
|
||||||
|
|
Loading…
Reference in New Issue