Merge pull request #74998 from mbohlool/pippin

Webhook configurations can choose which version of Review request they accept

Kubernetes-commit: e318642946daab9e0330757a3556a1913bb3fc5c
This commit is contained in:
Kubernetes Publisher 2019-03-08 03:01:26 -08:00
commit 7b53d00e2c
5 changed files with 244 additions and 186 deletions

74
Godeps/Godeps.json generated
View File

@ -928,151 +928,151 @@
},
{
"ImportPath": "k8s.io/api/admission/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/apps/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/apps/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/apps/v1beta2",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/auditregistration/v1alpha1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/authentication/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/authentication/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/authorization/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/authorization/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/autoscaling/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/autoscaling/v2beta2",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/batch/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/batch/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/batch/v2alpha1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/certificates/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/coordination/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/coordination/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/core/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/events/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/extensions/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/networking/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/networking/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/node/v1alpha1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/node/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/policy/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/rbac/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/rbac/v1alpha1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/rbac/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/scheduling/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/scheduling/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/settings/v1alpha1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/storage/v1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/storage/v1alpha1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/api/storage/v1beta1",
"Rev": "abf273d0e3378f540359565745ae19a00bfd47e1"
"Rev": "86b776c7fee02370596bf4913f7001f5ff638c55"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",

View File

@ -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
request := request.CreateAdmissionReview(attr)
client, err := a.cm.HookClient(util.HookClientConfigForWebhook(h))

View File

@ -212,6 +212,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Operations: []registrationv1beta1.OperationType{registrationv1beta1.Create},
}},
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
},
@ -222,6 +223,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("allow"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
@ -233,6 +235,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("disallow"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ErrorContains: "without explanation",
},
@ -243,6 +246,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("disallowReason"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ErrorContains: "you shall not pass",
@ -260,6 +264,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Operator: metav1.LabelSelectorOpIn,
}},
},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
@ -277,6 +282,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Operator: metav1.LabelSelectorOpNotIn,
}},
},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
},
@ -288,18 +294,21 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}, {
Name: "internalErr B",
ClientConfig: ccfgSVC("internalErr"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}, {
Name: "internalErr C",
ClientConfig: ccfgSVC("internalErr"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
@ -311,16 +320,19 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("internalErr"),
NamespaceSelector: &metav1.LabelSelector{},
Rules: matchEverythingRules,
AdmissionReviewVersions: []string{"v1beta1"},
}, {
Name: "internalErr B",
ClientConfig: ccfgSVC("internalErr"),
NamespaceSelector: &metav1.LabelSelector{},
Rules: matchEverythingRules,
AdmissionReviewVersions: []string{"v1beta1"},
}, {
Name: "internalErr C",
ClientConfig: ccfgSVC("internalErr"),
NamespaceSelector: &metav1.LabelSelector{},
Rules: matchEverythingRules,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: false,
},
@ -332,18 +344,21 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyFail,
AdmissionReviewVersions: []string{"v1beta1"},
}, {
Name: "internalErr B",
ClientConfig: ccfgSVC("internalErr"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyFail,
AdmissionReviewVersions: []string{"v1beta1"},
}, {
Name: "internalErr C",
ClientConfig: ccfgSVC("internalErr"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyFail,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: false,
},
@ -354,6 +369,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgURL("allow"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
@ -365,6 +381,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgURL("disallow"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ErrorContains: "without explanation",
}, {
@ -375,6 +392,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
FailurePolicy: &policyIgnore,
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
},
@ -386,6 +404,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
FailurePolicy: &policyFail,
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ErrorContains: "Webhook response was absent",
},
@ -399,6 +418,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
}},
NamespaceSelector: &metav1.LabelSelector{},
SideEffects: &sideEffectsSome,
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsDryRun: true,
ExpectAllow: true,
@ -411,6 +431,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
SideEffects: &sideEffectsUnknown,
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsDryRun: true,
ErrorContains: "does not support dry run",
@ -423,6 +444,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
SideEffects: &sideEffectsNone,
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsDryRun: true,
ExpectAllow: true,
@ -436,6 +458,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
SideEffects: &sideEffectsSome,
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsDryRun: true,
ErrorContains: "does not support dry run",
@ -448,6 +471,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
SideEffects: &sideEffectsNoneOnDryRun,
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsDryRun: true,
ExpectAllow: true,
@ -460,6 +484,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgURL("invalidAnnotation"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
},
@ -480,6 +505,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("removeLabel"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
AdditionalLabels: map[string]string{"remove": "me"},
@ -493,6 +519,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("addLabel"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectLabels: map[string]string{"pod.name": "my-pod", "added": "test"},
@ -504,6 +531,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("addLabel"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsCRD: true,
ExpectAllow: true,
@ -516,6 +544,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("removeLabel"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsCRD: true,
ExpectAllow: true,
@ -530,6 +559,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
ClientConfig: ccfgSVC("invalidMutation"),
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
AdmissionReviewVersions: []string{"v1beta1"},
}},
ErrorContains: "invalid character",
},
@ -541,6 +571,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
Rules: matchEverythingRules,
NamespaceSelector: &metav1.LabelSelector{},
SideEffects: &sideEffectsUnknown,
AdmissionReviewVersions: []string{"v1beta1"},
}},
IsDryRun: true,
ErrorContains: "does not support dry run",
@ -572,6 +603,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
Rules: newMatchEverythingRules(),
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectCacheMiss: true,
@ -584,6 +616,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
Rules: newMatchEverythingRules(),
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectCacheMiss: true,
@ -596,6 +629,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
Rules: newMatchEverythingRules(),
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectCacheMiss: false,
@ -608,6 +642,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
Rules: newMatchEverythingRules(),
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectCacheMiss: true,
@ -620,6 +655,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
Rules: newMatchEverythingRules(),
NamespaceSelector: &metav1.LabelSelector{},
FailurePolicy: &policyIgnore,
AdmissionReviewVersions: []string{"v1beta1"},
}},
ExpectAllow: true,
ExpectCacheMiss: false,

View File

@ -40,3 +40,13 @@ func HookClientConfigForWebhook(w *v1beta1.Webhook) webhook.ClientConfig {
}
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
}

View File

@ -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
request := request.CreateAdmissionReview(attr)
client, err := d.cm.HookClient(util.HookClientConfigForWebhook(h))