Update tests for: Pass {Operation}Option to Webhooks

This commit is contained in:
Joe Betz
2019-05-07 13:37:07 -07:00
parent 332d88db1a
commit 900d652a9a
45 changed files with 473 additions and 378 deletions

View File

@@ -22,6 +22,7 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
], ],
) )

View File

@@ -19,13 +19,14 @@ package admit
import ( import (
"testing" "testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
) )
func TestAdmissionNonNilAttribute(t *testing.T) { func TestAdmissionNonNilAttribute(t *testing.T) {
handler := NewAlwaysAdmit() handler := NewAlwaysAdmit()
err := handler.(*alwaysAdmit).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil), nil) err := handler.(*alwaysAdmit).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error returned from admission handler") t.Errorf("Unexpected error returned from admission handler")
} }

View File

@@ -47,7 +47,7 @@ func TestAdmission(t *testing.T) {
}, },
}, },
} }
err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error returned from admission handler") t.Errorf("Unexpected error returned from admission handler")
} }
@@ -84,7 +84,7 @@ func TestValidate(t *testing.T) {
}, },
} }
expectedError := `pods "123" is forbidden: spec.initContainers[0].imagePullPolicy: Unsupported value: "": supported values: "Always"` expectedError := `pods "123" is forbidden: spec.initContainers[0].imagePullPolicy: Unsupported value: "": supported values: "Always"`
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Fatal("missing expected error") t.Fatal("missing expected error")
} }
@@ -139,7 +139,7 @@ func TestOtherResources(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
handler := &AlwaysPullImages{} handler := &AlwaysPullImages{}
err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil), nil) err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if tc.expectError { if tc.expectError {
if err == nil { if err == nil {

View File

@@ -19,7 +19,7 @@ package antiaffinity
import ( import (
"testing" "testing"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
@@ -199,7 +199,7 @@ func TestInterPodAffinityAdmission(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
pod.Spec.Affinity = test.affinity pod.Spec.Affinity = test.affinity
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil, false, nil), nil)
if test.errorExpected && err == nil { if test.errorExpected && err == nil {
t.Errorf("Expected error for Anti Affinity %+v but did not get an error", test.affinity) t.Errorf("Expected error for Anti Affinity %+v but did not get an error", test.affinity)
@@ -267,7 +267,7 @@ func TestOtherResources(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
handler := &Plugin{} handler := &Plugin{}
err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if tc.expectError { if tc.expectError {
if err == nil { if err == nil {

View File

@@ -263,7 +263,7 @@ func TestForgivenessAdmission(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil) err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod) t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
} }

View File

@@ -22,6 +22,7 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
], ],
) )

View File

@@ -19,13 +19,14 @@ package deny
import ( import (
"testing" "testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
) )
func TestAdmission(t *testing.T) { func TestAdmission(t *testing.T) {
handler := NewAlwaysDeny() handler := NewAlwaysDeny()
err := handler.(*alwaysDeny).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil), nil) err := handler.(*alwaysDeny).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Error("Expected error returned from admission handler") t.Error("Expected error returned from admission handler")
} }

View File

@@ -17,6 +17,7 @@ go_test(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit:go_default_library", "//plugin/pkg/admission/eventratelimit/apis/eventratelimit:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",

View File

@@ -21,6 +21,7 @@ import (
"time" "time"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/clock" "k8s.io/apimachinery/pkg/util/clock"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
@@ -46,6 +47,7 @@ func attributesForRequest(rq request) admission.Attributes {
api.Resource("resource").WithVersion("version"), api.Resource("resource").WithVersion("version"),
"", "",
admission.Create, admission.Create,
&metav1.CreateOptions{},
rq.dryRun, rq.dryRun,
&user.DefaultInfo{Name: rq.username}) &user.DefaultInfo{Name: rq.username})
} }

View File

@@ -120,7 +120,7 @@ func testAdmission(t *testing.T, pod *corev1.Pod, handler *DenyExec, shouldAccep
// pods/exec // pods/exec
{ {
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "exec", admission.Connect, nil, false, nil), nil)
if shouldAccept && err != nil { if shouldAccept && err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err) t.Errorf("Unexpected error returned from admission handler: %v", err)
} }
@@ -131,7 +131,7 @@ func testAdmission(t *testing.T, pod *corev1.Pod, handler *DenyExec, shouldAccep
// pods/attach // pods/attach
{ {
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "attach", admission.Connect, nil, false, nil), nil)
if shouldAccept && err != nil { if shouldAccept && err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err) t.Errorf("Unexpected error returned from admission handler: %v", err)
} }

View File

@@ -354,7 +354,7 @@ func TestAdmit(t *testing.T) {
}, },
} }
for i, test := range tests { for i, test := range tests {
err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil) err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", nil, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("[%d: %s] unexpected error %v for pod %+v", i, test.description, err, test.requestedPod) t.Errorf("[%d: %s] unexpected error %v for pod %+v", i, test.description, err, test.requestedPod)
} }

View File

@@ -302,11 +302,13 @@ func TestGCAdmission(t *testing.T) {
} }
operation := admission.Create operation := admission.Create
var options runtime.Object = &metav1.CreateOptions{}
if tc.oldObj != nil { if tc.oldObj != nil {
operation = admission.Update operation = admission.Update
options = &metav1.UpdateOptions{}
} }
user := &user.DefaultInfo{Name: tc.username} user := &user.DefaultInfo{Name: tc.username}
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user) attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, options, false, user)
err = gcAdmit.Validate(attributes, nil) err = gcAdmit.Validate(attributes, nil)
if !tc.checkError(err) { if !tc.checkError(err) {
@@ -605,11 +607,13 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
operation := admission.Create operation := admission.Create
var options runtime.Object = &metav1.CreateOptions{}
if tc.oldObj != nil { if tc.oldObj != nil {
operation = admission.Update operation = admission.Update
options = &metav1.UpdateOptions{}
} }
user := &user.DefaultInfo{Name: tc.username} user := &user.DefaultInfo{Name: tc.username}
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user) attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, options, false, user)
err := gcAdmit.Validate(attributes, nil) err := gcAdmit.Validate(attributes, nil)
if !tc.checkError(err) { if !tc.checkError(err) {

View File

@@ -42,6 +42,7 @@ go_test(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/imagepolicy/install:go_default_library", "//pkg/apis/imagepolicy/install:go_default_library",
"//staging/src/k8s.io/api/imagepolicy/v1alpha1:go_default_library", "//staging/src/k8s.io/api/imagepolicy/v1alpha1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",

View File

@@ -29,9 +29,10 @@ import (
"time" "time"
"k8s.io/api/imagepolicy/v1alpha1" "k8s.io/api/imagepolicy/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/tools/clientcmd/api/v1" v1 "k8s.io/client-go/tools/clientcmd/api/v1"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"fmt" "fmt"
@@ -482,7 +483,7 @@ func TestTLSConfig(t *testing.T) {
return return
} }
pod := goodPod(strconv.Itoa(rand.Intn(1000))) pod := goodPod(strconv.Itoa(rand.Intn(1000)))
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{}) attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
// Allow all and see if we get an error. // Allow all and see if we get an error.
service.Allow() service.Allow()
@@ -571,7 +572,7 @@ func TestWebhookCache(t *testing.T) {
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true}, {statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
} }
attr := admission.NewAttributesRecord(goodPod("test"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{}) attr := admission.NewAttributesRecord(goodPod("test"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
serv.allow = true serv.allow = true
@@ -583,7 +584,7 @@ func TestWebhookCache(t *testing.T) {
{statusCode: 200, expectedErr: false, expectedAuthorized: true, expectedCached: false}, {statusCode: 200, expectedErr: false, expectedAuthorized: true, expectedCached: false},
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true}, {statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
} }
attr = admission.NewAttributesRecord(goodPod("test2"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{}) attr = admission.NewAttributesRecord(goodPod("test2"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
testWebhookCacheCases(t, serv, wh, attr, tests) testWebhookCacheCases(t, serv, wh, attr, tests)
} }
@@ -757,7 +758,7 @@ func TestContainerCombinations(t *testing.T) {
return return
} }
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{}) attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
err = wh.Validate(attr, nil) err = wh.Validate(attr, nil)
if tt.wantAllowed { if tt.wantAllowed {
@@ -851,7 +852,7 @@ func TestDefaultAllow(t *testing.T) {
return return
} }
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{}) attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
annotations := make(map[string]string) annotations := make(map[string]string)
attr = &fakeAttributes{attr, annotations} attr = &fakeAttributes{attr, annotations}
@@ -961,7 +962,7 @@ func TestAnnotationFiltering(t *testing.T) {
pod := goodPod("test") pod := goodPod("test")
pod.Annotations = tt.annotations pod.Annotations = tt.annotations
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{}) attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
err = wh.Validate(attr, nil) err = wh.Validate(attr, nil)
if err != nil { if err != nil {
@@ -1051,7 +1052,7 @@ func TestReturnedAnnotationAdd(t *testing.T) {
pod := tt.pod pod := tt.pod
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{}) attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
annotations := make(map[string]string) annotations := make(map[string]string)
attr = &fakeAttributes{attr, annotations} attr = &fakeAttributes{attr, annotations}

View File

@@ -35,7 +35,7 @@ import (
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/core/v1" v1 "k8s.io/kubernetes/pkg/apis/core/v1"
) )
func getComputeResourceList(cpu, memory string) api.ResourceList { func getComputeResourceList(cpu, memory string) api.ResourceList {
@@ -705,20 +705,20 @@ func TestLimitRangerIgnoresSubresource(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
testPod := validPod("testPod", 1, api.ResourceRequirements{}) testPod := validPod("testPod", 1, api.ResourceRequirements{})
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error since the pod did not specify resource limits in its create call") t.Errorf("Expected an error since the pod did not specify resource limits in its create call")
} }
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Expected not to call limitranger actions on pod updates") t.Errorf("Expected not to call limitranger actions on pod updates")
} }
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Should have ignored calls to any subresource of pod %v", err) t.Errorf("Should have ignored calls to any subresource of pod %v", err)
} }
@@ -735,20 +735,20 @@ func TestLimitRangerAdmitPod(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
testPod := validPod("testPod", 1, api.ResourceRequirements{}) testPod := validPod("testPod", 1, api.ResourceRequirements{})
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error since the pod did not specify resource limits in its create call") t.Errorf("Expected an error since the pod did not specify resource limits in its create call")
} }
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Expected not to call limitranger actions on pod updates") t.Errorf("Expected not to call limitranger actions on pod updates")
} }
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Should have ignored calls to any subresource of pod %v", err) t.Errorf("Should have ignored calls to any subresource of pod %v", err)
} }
@@ -757,7 +757,7 @@ func TestLimitRangerAdmitPod(t *testing.T) {
terminatingPod := validPod("terminatingPod", 1, api.ResourceRequirements{}) terminatingPod := validPod("terminatingPod", 1, api.ResourceRequirements{})
now := metav1.Now() now := metav1.Now()
terminatingPod.DeletionTimestamp = &now terminatingPod.DeletionTimestamp = &now
err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("LimitRange should ignore a pod marked for termination") t.Errorf("LimitRange should ignore a pod marked for termination")
} }

View File

@@ -99,7 +99,7 @@ func TestAdmission(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error returned from admission handler") t.Errorf("unexpected error returned from admission handler")
} }
@@ -119,7 +119,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error returned from admission handler") t.Errorf("unexpected error returned from admission handler")
} }
@@ -139,7 +139,7 @@ func TestAdmissionDryRun(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, true, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, true, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error returned from admission handler") t.Errorf("unexpected error returned from admission handler")
} }
@@ -160,7 +160,7 @@ func TestIgnoreAdmission(t *testing.T) {
chainHandler := admission.NewChainHandler(handler) chainHandler := admission.NewChainHandler(handler)
pod := newPod(namespace) pod := newPod(namespace)
err = chainHandler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil) err = chainHandler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error returned from admission handler") t.Errorf("unexpected error returned from admission handler")
} }
@@ -182,7 +182,7 @@ func TestAdmissionWithLatentCache(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error returned from admission handler") t.Errorf("unexpected error returned from admission handler")
} }

View File

@@ -88,7 +88,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error returned from admission handler") t.Errorf("unexpected error returned from admission handler")
} }
@@ -108,7 +108,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
actions := "" actions := ""
for _, action := range mockClient.Actions() { for _, action := range mockClient.Actions() {

View File

@@ -374,61 +374,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "allow creating a mirror pod bound to self", name: "allow creating a mirror pod bound to self",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coremymirrorpod, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coremymirrorpod, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid update of mirror pod bound to self", name: "forbid update of mirror pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coremymirrorpod, coremymirrorpod, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coremymirrorpod, coremymirrorpod, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "allow delete of mirror pod bound to self", name: "allow delete of mirror pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid create of mirror pod status bound to self", name: "forbid create of mirror pod status bound to self",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coremymirrorpod, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "status", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coremymirrorpod, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "status", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "allow update of mirror pod status bound to self", name: "allow update of mirror pod status bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coremymirrorpod, coremymirrorpod, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coremymirrorpod, coremymirrorpod, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid delete of mirror pod status bound to self", name: "forbid delete of mirror pod status bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "status", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "status", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "allow create of eviction for mirror pod bound to self", name: "allow create of eviction for mirror pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid update of eviction for mirror pod bound to self", name: "forbid update of eviction for mirror pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for mirror pod bound to self", name: "forbid delete of eviction for mirror pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "allow create of unnamed eviction for mirror pod bound to self", name: "allow create of unnamed eviction for mirror pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coremymirrorpod.Namespace, coremymirrorpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
@@ -436,61 +436,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid creating a mirror pod bound to another", name: "forbid creating a mirror pod bound to another",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreothermirrorpod, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreothermirrorpod, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid update of mirror pod bound to another", name: "forbid update of mirror pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreothermirrorpod, coreothermirrorpod, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreothermirrorpod, coreothermirrorpod, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of mirror pod bound to another", name: "forbid delete of mirror pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid create of mirror pod status bound to another", name: "forbid create of mirror pod status bound to another",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreothermirrorpod, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "status", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreothermirrorpod, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "status", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid update of mirror pod status bound to another", name: "forbid update of mirror pod status bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreothermirrorpod, coreothermirrorpod, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreothermirrorpod, coreothermirrorpod, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid delete of mirror pod status bound to another", name: "forbid delete of mirror pod status bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "status", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "status", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of eviction for mirror pod bound to another", name: "forbid create of eviction for mirror pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid update of eviction for mirror pod bound to another", name: "forbid update of eviction for mirror pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for mirror pod bound to another", name: "forbid delete of eviction for mirror pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of unnamed eviction for mirror pod to another", name: "forbid create of unnamed eviction for mirror pod to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreothermirrorpod.Namespace, coreothermirrorpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
@@ -498,61 +498,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid creating a mirror pod unbound", name: "forbid creating a mirror pod unbound",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreunboundmirrorpod, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreunboundmirrorpod, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid update of mirror pod unbound", name: "forbid update of mirror pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreunboundmirrorpod, coreunboundmirrorpod, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreunboundmirrorpod, coreunboundmirrorpod, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of mirror pod unbound", name: "forbid delete of mirror pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid create of mirror pod status unbound", name: "forbid create of mirror pod status unbound",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreunboundmirrorpod, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "status", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreunboundmirrorpod, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "status", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid update of mirror pod status unbound", name: "forbid update of mirror pod status unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreunboundmirrorpod, coreunboundmirrorpod, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreunboundmirrorpod, coreunboundmirrorpod, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid delete of mirror pod status unbound", name: "forbid delete of mirror pod status unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "status", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "status", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of eviction for mirror pod unbound", name: "forbid create of eviction for mirror pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid update of eviction for mirror pod unbound", name: "forbid update of eviction for mirror pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for mirror pod unbound", name: "forbid delete of eviction for mirror pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of unnamed eviction for mirror pod unbound", name: "forbid create of unnamed eviction for mirror pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreunboundmirrorpod.Namespace, coreunboundmirrorpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
@@ -560,55 +560,55 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid creating a normal pod bound to self", name: "forbid creating a normal pod bound to self",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coremypod, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coremypod, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "can only create mirror pods", err: "can only create mirror pods",
}, },
{ {
name: "forbid update of normal pod bound to self", name: "forbid update of normal pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coremypod, coremypod, podKind, coremypod.Namespace, coremypod.Name, podResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coremypod, coremypod, podKind, coremypod.Namespace, coremypod.Name, podResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "allow delete of normal pod bound to self", name: "allow delete of normal pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid create of normal pod status bound to self", name: "forbid create of normal pod status bound to self",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coremypod, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "status", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coremypod, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "status", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "allow update of normal pod status bound to self", name: "allow update of normal pod status bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coremypod, coremypod, podKind, coremypod.Namespace, coremypod.Name, podResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coremypod, coremypod, podKind, coremypod.Namespace, coremypod.Name, podResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid delete of normal pod status bound to self", name: "forbid delete of normal pod status bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "status", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coremypod.Namespace, coremypod.Name, podResource, "status", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid update of eviction for normal pod bound to self", name: "forbid update of eviction for normal pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for normal pod bound to self", name: "forbid delete of eviction for normal pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "allow create of unnamed eviction for normal pod bound to self", name: "allow create of unnamed eviction for normal pod bound to self",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
@@ -616,61 +616,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid creating a normal pod bound to another", name: "forbid creating a normal pod bound to another",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreotherpod, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreotherpod, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "can only create mirror pods", err: "can only create mirror pods",
}, },
{ {
name: "forbid update of normal pod bound to another", name: "forbid update of normal pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreotherpod, coreotherpod, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreotherpod, coreotherpod, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of normal pod bound to another", name: "forbid delete of normal pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "", admission.Delete, &metav1.UpdateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid create of normal pod status bound to another", name: "forbid create of normal pod status bound to another",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreotherpod, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "status", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreotherpod, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "status", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid update of normal pod status bound to another", name: "forbid update of normal pod status bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreotherpod, coreotherpod, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreotherpod, coreotherpod, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid delete of normal pod status bound to another", name: "forbid delete of normal pod status bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "status", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "status", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of eviction for normal pod bound to another", name: "forbid create of eviction for normal pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid update of eviction for normal pod bound to another", name: "forbid update of eviction for normal pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for normal pod bound to another", name: "forbid delete of eviction for normal pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Delete, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of unnamed eviction for normal pod bound to another", name: "forbid create of unnamed eviction for normal pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreotherpod.Namespace, coreotherpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
@@ -678,61 +678,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid creating a normal pod unbound", name: "forbid creating a normal pod unbound",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "can only create mirror pods", err: "can only create mirror pods",
}, },
{ {
name: "forbid update of normal pod unbound", name: "forbid update of normal pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of normal pod unbound", name: "forbid delete of normal pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid create of normal pod status unbound", name: "forbid create of normal pod status unbound",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid update of normal pod status unbound", name: "forbid update of normal pod status unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid delete of normal pod status unbound", name: "forbid delete of normal pod status unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of eviction for normal pod unbound", name: "forbid create of eviction for normal pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
{ {
name: "forbid update of eviction for normal pod unbound", name: "forbid update of eviction for normal pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for normal pod unbound", name: "forbid delete of eviction for normal pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of unnamed eviction for normal unbound", name: "forbid create of unnamed eviction for normal unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",
}, },
@@ -740,31 +740,31 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid delete of unknown pod", name: "forbid delete of unknown pod",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "not found", err: "not found",
}, },
{ {
name: "forbid create of eviction for unknown pod", name: "forbid create of eviction for unknown pod",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "not found", err: "not found",
}, },
{ {
name: "forbid update of eviction for unknown pod", name: "forbid update of eviction for unknown pod",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for unknown pod", name: "forbid delete of eviction for unknown pod",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of unnamed eviction for unknown pod", name: "forbid create of unnamed eviction for unknown pod",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coremypod.Namespace, coremypod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "not found", err: "not found",
}, },
@@ -772,26 +772,26 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "allow create of eviction for unnamed pod", name: "allow create of eviction for unnamed pod",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
// use the submitted eviction resource name as the pod name // use the submitted eviction resource name as the pod name
err: "", err: "",
}, },
{ {
name: "forbid update of eviction for unnamed pod", name: "forbid update of eviction for unnamed pod",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid delete of eviction for unnamed pod", name: "forbid delete of eviction for unnamed pod",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of unnamed eviction for unnamed pod", name: "forbid create of unnamed eviction for unnamed pod",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, coreunnamedpod.Namespace, coreunnamedpod.Name, podResource, "eviction", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "could not determine pod from request data", err: "could not determine pod from request data",
}, },
@@ -799,25 +799,25 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid create of pod referencing service account", name: "forbid create of pod referencing service account",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(sapod, nil, podKind, sapod.Namespace, sapod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(sapod, nil, podKind, sapod.Namespace, sapod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "reference a service account", err: "reference a service account",
}, },
{ {
name: "forbid create of pod referencing secret", name: "forbid create of pod referencing secret",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(secretpod, nil, podKind, secretpod.Namespace, secretpod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(secretpod, nil, podKind, secretpod.Namespace, secretpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "reference secrets", err: "reference secrets",
}, },
{ {
name: "forbid create of pod referencing configmap", name: "forbid create of pod referencing configmap",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(configmappod, nil, podKind, configmappod.Namespace, configmappod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(configmappod, nil, podKind, configmappod.Namespace, configmappod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "reference configmaps", err: "reference configmaps",
}, },
{ {
name: "forbid create of pod referencing persistentvolumeclaim", name: "forbid create of pod referencing persistentvolumeclaim",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "reference persistentvolumeclaims", err: "reference persistentvolumeclaims",
}, },
@@ -825,157 +825,157 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "allow create of my node", name: "allow create of my node",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow create of my node pulling name from object", name: "allow create of my node pulling name from object",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow create of my node with taints", name: "allow create of my node with taints",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(mynodeObjTaintA, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjTaintA, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow create of my node with labels", name: "allow create of my node with labels",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(setAllowedCreateLabels(mynodeObj, ""), nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(setAllowedCreateLabels(mynodeObj, ""), nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid create of my node with forbidden labels", name: "forbid create of my node with forbidden labels",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(setForbiddenCreateLabels(mynodeObj, ""), nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(setForbiddenCreateLabels(mynodeObj, ""), nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: `is not allowed to set the following labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo`, err: `is not allowed to set the following labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo`,
}, },
{ {
name: "allow update of my node", name: "allow update of my node",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow delete of my node", name: "allow delete of my node",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node status", name: "allow update of my node status",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid create of my node with non-nil configSource", name: "forbid create of my node with non-nil configSource",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(mynodeObjConfigA, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjConfigA, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "is not allowed to create pods with a non-nil configSource", err: "is not allowed to create pods with a non-nil configSource",
}, },
{ {
name: "forbid update of my node: nil configSource to new non-nil configSource", name: "forbid update of my node: nil configSource to new non-nil configSource",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "update configSource to a new non-nil configSource", err: "update configSource to a new non-nil configSource",
}, },
{ {
name: "forbid update of my node: non-nil configSource to new non-nil configSource", name: "forbid update of my node: non-nil configSource to new non-nil configSource",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjConfigB, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjConfigB, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "update configSource to a new non-nil configSource", err: "update configSource to a new non-nil configSource",
}, },
{ {
name: "allow update of my node: non-nil configSource unchanged", name: "allow update of my node: non-nil configSource unchanged",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: non-nil configSource to nil configSource", name: "allow update of my node: non-nil configSource to nil configSource",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: no change to taints", name: "allow update of my node: no change to taints",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: add allowed labels", name: "allow update of my node: add allowed labels",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(setAllowedUpdateLabels(mynodeObj, ""), mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(setAllowedUpdateLabels(mynodeObj, ""), mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: remove allowed labels", name: "allow update of my node: remove allowed labels",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObj, setAllowedUpdateLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, setAllowedUpdateLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: modify allowed labels", name: "allow update of my node: modify allowed labels",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(setAllowedUpdateLabels(mynodeObj, "b"), setAllowedUpdateLabels(mynodeObj, "a"), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(setAllowedUpdateLabels(mynodeObj, "b"), setAllowedUpdateLabels(mynodeObj, "a"), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: no change to labels", name: "allow update of my node: no change to labels",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(setAllLabels(mynodeObj, ""), setAllLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(setAllLabels(mynodeObj, ""), setAllLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: add allowed labels while forbidden labels exist unmodified", name: "allow update of my node: add allowed labels while forbidden labels exist unmodified",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(setAllLabels(mynodeObj, ""), setForbiddenUpdateLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(setAllLabels(mynodeObj, ""), setForbiddenUpdateLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of my node: remove allowed labels while forbidden labels exist unmodified", name: "allow update of my node: remove allowed labels while forbidden labels exist unmodified",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(setForbiddenUpdateLabels(mynodeObj, ""), setAllLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(setForbiddenUpdateLabels(mynodeObj, ""), setAllLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "forbid update of my node: add taints", name: "forbid update of my node: add taints",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "is not allowed to modify taints", err: "is not allowed to modify taints",
}, },
{ {
name: "forbid update of my node: remove taints", name: "forbid update of my node: remove taints",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "is not allowed to modify taints", err: "is not allowed to modify taints",
}, },
{ {
name: "forbid update of my node: change taints", name: "forbid update of my node: change taints",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintB, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintB, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "is not allowed to modify taints", err: "is not allowed to modify taints",
}, },
{ {
name: "forbid update of my node: add labels", name: "forbid update of my node: add labels",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(setForbiddenUpdateLabels(mynodeObj, ""), mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(setForbiddenUpdateLabels(mynodeObj, ""), mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: `is not allowed to modify labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo, other.k8s.io/foo, other.kubernetes.io/foo`, err: `is not allowed to modify labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo, other.k8s.io/foo, other.kubernetes.io/foo`,
}, },
{ {
name: "forbid update of my node: remove labels", name: "forbid update of my node: remove labels",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObj, setForbiddenUpdateLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(mynodeObj, setForbiddenUpdateLabels(mynodeObj, ""), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: `is not allowed to modify labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo, other.k8s.io/foo, other.kubernetes.io/foo`, err: `is not allowed to modify labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo, other.k8s.io/foo, other.kubernetes.io/foo`,
}, },
{ {
name: "forbid update of my node: change labels", name: "forbid update of my node: change labels",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(setForbiddenUpdateLabels(mynodeObj, "new"), setForbiddenUpdateLabels(mynodeObj, "old"), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(setForbiddenUpdateLabels(mynodeObj, "new"), setForbiddenUpdateLabels(mynodeObj, "old"), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: `is not allowed to modify labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo, other.k8s.io/foo, other.kubernetes.io/foo`, err: `is not allowed to modify labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo, other.k8s.io/foo, other.kubernetes.io/foo`,
}, },
@@ -983,31 +983,31 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "forbid create of other node", name: "forbid create of other node",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "is not allowed to modify node", err: "is not allowed to modify node",
}, },
{ {
name: "forbid create of other node pulling name from object", name: "forbid create of other node pulling name from object",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, "", nodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "is not allowed to modify node", err: "is not allowed to modify node",
}, },
{ {
name: "forbid update of other node", name: "forbid update of other node",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "is not allowed to modify node", err: "is not allowed to modify node",
}, },
{ {
name: "forbid delete of other node", name: "forbid delete of other node",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "is not allowed to modify node", err: "is not allowed to modify node",
}, },
{ {
name: "forbid update of other node status", name: "forbid update of other node status",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "status", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "status", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "is not allowed to modify node", err: "is not allowed to modify node",
}, },
@@ -1016,54 +1016,54 @@ func Test_nodePlugin_Admit(t *testing.T) {
name: "forbid create of unbound token", name: "forbid create of unbound token",
podsGetter: noExistingPods, podsGetter: noExistingPods,
features: trEnabledFeature, features: trEnabledFeature,
attributes: admission.NewAttributesRecord(makeTokenRequest("", ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(makeTokenRequest("", ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "not bound to a pod", err: "not bound to a pod",
}, },
{ {
name: "forbid create of token bound to nonexistant pod", name: "forbid create of token bound to nonexistant pod",
podsGetter: noExistingPods, podsGetter: noExistingPods,
features: trEnabledFeature, features: trEnabledFeature,
attributes: admission.NewAttributesRecord(makeTokenRequest("nopod", "someuid"), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(makeTokenRequest("nopod", "someuid"), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "not found", err: "not found",
}, },
{ {
name: "forbid create of token bound to pod without uid", name: "forbid create of token bound to pod without uid",
podsGetter: existingPods, podsGetter: existingPods,
features: trEnabledFeature, features: trEnabledFeature,
attributes: admission.NewAttributesRecord(makeTokenRequest(coremypod.Name, ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(makeTokenRequest(coremypod.Name, ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "pod binding without a uid", err: "pod binding without a uid",
}, },
{ {
name: "forbid create of token bound to pod scheduled on another node", name: "forbid create of token bound to pod scheduled on another node",
podsGetter: existingPods, podsGetter: existingPods,
features: trEnabledFeature, features: trEnabledFeature,
attributes: admission.NewAttributesRecord(makeTokenRequest(coreotherpod.Name, coreotherpod.UID), nil, tokenrequestKind, coreotherpod.Namespace, "mysa", svcacctResource, "token", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(makeTokenRequest(coreotherpod.Name, coreotherpod.UID), nil, tokenrequestKind, coreotherpod.Namespace, "mysa", svcacctResource, "token", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "pod scheduled on a different node", err: "pod scheduled on a different node",
}, },
{ {
name: "allow create of token bound to pod scheduled this node", name: "allow create of token bound to pod scheduled this node",
podsGetter: existingPods, podsGetter: existingPods,
features: trEnabledFeature, features: trEnabledFeature,
attributes: admission.NewAttributesRecord(makeTokenRequest(coremypod.Name, coremypod.UID), nil, tokenrequestKind, coremypod.Namespace, "mysa", svcacctResource, "token", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(makeTokenRequest(coremypod.Name, coremypod.UID), nil, tokenrequestKind, coremypod.Namespace, "mysa", svcacctResource, "token", admission.Create, &metav1.CreateOptions{}, false, mynode),
}, },
// Unrelated objects // Unrelated objects
{ {
name: "allow create of unrelated object", name: "allow create of unrelated object",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(&api.ConfigMap{}, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(&api.ConfigMap{}, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow update of unrelated object", name: "allow update of unrelated object",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(&api.ConfigMap{}, &api.ConfigMap{}, configmapKind, "myns", "mycm", configmapResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(&api.ConfigMap{}, &api.ConfigMap{}, configmapKind, "myns", "mycm", configmapResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "", err: "",
}, },
{ {
name: "allow delete of unrelated object", name: "allow delete of unrelated object",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
err: "", err: "",
}, },
@@ -1071,140 +1071,140 @@ func Test_nodePlugin_Admit(t *testing.T) {
{ {
name: "allow unrelated user creating a normal pod unbound", name: "allow unrelated user creating a normal pod unbound",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Create, false, bob), attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, bob),
err: "", err: "",
}, },
{ {
name: "allow unrelated user update of normal pod unbound", name: "allow unrelated user update of normal pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Update, false, bob), attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Update, &metav1.UpdateOptions{}, false, bob),
err: "", err: "",
}, },
{ {
name: "allow unrelated user delete of normal pod unbound", name: "allow unrelated user delete of normal pod unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Delete, false, bob), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "", admission.Delete, &metav1.DeleteOptions{}, false, bob),
err: "", err: "",
}, },
{ {
name: "allow unrelated user create of normal pod status unbound", name: "allow unrelated user create of normal pod status unbound",
podsGetter: noExistingPods, podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Create, false, bob), attributes: admission.NewAttributesRecord(coreunboundpod, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Create, &metav1.CreateOptions{}, false, bob),
err: "", err: "",
}, },
{ {
name: "allow unrelated user update of normal pod status unbound", name: "allow unrelated user update of normal pod status unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Update, false, bob), attributes: admission.NewAttributesRecord(coreunboundpod, coreunboundpod, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Update, &metav1.UpdateOptions{}, false, bob),
err: "", err: "",
}, },
{ {
name: "allow unrelated user delete of normal pod status unbound", name: "allow unrelated user delete of normal pod status unbound",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Delete, false, bob), attributes: admission.NewAttributesRecord(nil, nil, podKind, coreunboundpod.Namespace, coreunboundpod.Name, podResource, "status", admission.Delete, &metav1.DeleteOptions{}, false, bob),
err: "", err: "",
}, },
// Node leases // Node leases
{ {
name: "disallowed create lease - feature disabled", name: "disallowed create lease - feature disabled",
attributes: admission.NewAttributesRecord(lease, nil, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(lease, nil, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Create, &metav1.DeleteOptions{}, false, mynode),
features: leaseDisabledFeature, features: leaseDisabledFeature,
err: "forbidden: disabled by feature gate NodeLease", err: "forbidden: disabled by feature gate NodeLease",
}, },
{ {
name: "disallowed create lease in namespace other than kube-node-lease - feature enabled", name: "disallowed create lease in namespace other than kube-node-lease - feature enabled",
attributes: admission.NewAttributesRecord(leaseWrongNS, nil, leaseKind, leaseWrongNS.Namespace, leaseWrongNS.Name, leaseResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(leaseWrongNS, nil, leaseKind, leaseWrongNS.Namespace, leaseWrongNS.Name, leaseResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "disallowed update lease in namespace other than kube-node-lease - feature enabled", name: "disallowed update lease in namespace other than kube-node-lease - feature enabled",
attributes: admission.NewAttributesRecord(leaseWrongNS, leaseWrongNS, leaseKind, leaseWrongNS.Namespace, leaseWrongNS.Name, leaseResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(leaseWrongNS, leaseWrongNS, leaseKind, leaseWrongNS.Namespace, leaseWrongNS.Name, leaseResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "disallowed delete lease in namespace other than kube-node-lease - feature enabled", name: "disallowed delete lease in namespace other than kube-node-lease - feature enabled",
attributes: admission.NewAttributesRecord(nil, nil, leaseKind, leaseWrongNS.Namespace, leaseWrongNS.Name, leaseResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, leaseKind, leaseWrongNS.Namespace, leaseWrongNS.Name, leaseResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "disallowed create another node's lease - feature enabled", name: "disallowed create another node's lease - feature enabled",
attributes: admission.NewAttributesRecord(leaseWrongName, nil, leaseKind, leaseWrongName.Namespace, leaseWrongName.Name, leaseResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(leaseWrongName, nil, leaseKind, leaseWrongName.Namespace, leaseWrongName.Name, leaseResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "disallowed update another node's lease - feature enabled", name: "disallowed update another node's lease - feature enabled",
attributes: admission.NewAttributesRecord(leaseWrongName, leaseWrongName, leaseKind, leaseWrongName.Namespace, leaseWrongName.Name, leaseResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(leaseWrongName, leaseWrongName, leaseKind, leaseWrongName.Namespace, leaseWrongName.Name, leaseResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "disallowed delete another node's lease - feature enabled", name: "disallowed delete another node's lease - feature enabled",
attributes: admission.NewAttributesRecord(nil, nil, leaseKind, leaseWrongName.Namespace, leaseWrongName.Name, leaseResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, leaseKind, leaseWrongName.Namespace, leaseWrongName.Name, leaseResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "allowed create node lease - feature enabled", name: "allowed create node lease - feature enabled",
attributes: admission.NewAttributesRecord(lease, nil, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(lease, nil, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "", err: "",
}, },
{ {
name: "allowed update node lease - feature enabled", name: "allowed update node lease - feature enabled",
attributes: admission.NewAttributesRecord(lease, lease, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(lease, lease, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "", err: "",
}, },
{ {
name: "allowed delete node lease - feature enabled", name: "allowed delete node lease - feature enabled",
attributes: admission.NewAttributesRecord(nil, nil, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, leaseKind, lease.Namespace, lease.Name, leaseResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
features: leaseEnabledFeature, features: leaseEnabledFeature,
err: "", err: "",
}, },
// CSINode // CSINode
{ {
name: "disallowed create CSINode - feature disabled", name: "disallowed create CSINode - feature disabled",
attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
features: csiNodeInfoDisabledFeature, features: csiNodeInfoDisabledFeature,
err: fmt.Sprintf("forbidden: disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo), err: fmt.Sprintf("forbidden: disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo),
}, },
{ {
name: "disallowed create another node's CSINode - feature enabled", name: "disallowed create another node's CSINode - feature enabled",
attributes: admission.NewAttributesRecord(nodeInfoWrongName, nil, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(nodeInfoWrongName, nil, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
features: csiNodeInfoEnabledFeature, features: csiNodeInfoEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "disallowed update another node's CSINode - feature enabled", name: "disallowed update another node's CSINode - feature enabled",
attributes: admission.NewAttributesRecord(nodeInfoWrongName, nodeInfoWrongName, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(nodeInfoWrongName, nodeInfoWrongName, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
features: csiNodeInfoEnabledFeature, features: csiNodeInfoEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "disallowed delete another node's CSINode - feature enabled", name: "disallowed delete another node's CSINode - feature enabled",
attributes: admission.NewAttributesRecord(nil, nil, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Delete, &metav1.DeleteOptions{}, false, mynode),
features: csiNodeInfoEnabledFeature, features: csiNodeInfoEnabledFeature,
err: "forbidden: ", err: "forbidden: ",
}, },
{ {
name: "allowed create node CSINode - feature enabled", name: "allowed create node CSINode - feature enabled",
attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Create, false, mynode), attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
features: csiNodeInfoEnabledFeature, features: csiNodeInfoEnabledFeature,
err: "", err: "",
}, },
{ {
name: "allowed update node CSINode - feature enabled", name: "allowed update node CSINode - feature enabled",
attributes: admission.NewAttributesRecord(nodeInfo, nodeInfo, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Update, false, mynode), attributes: admission.NewAttributesRecord(nodeInfo, nodeInfo, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
features: csiNodeInfoEnabledFeature, features: csiNodeInfoEnabledFeature,
err: "", err: "",
}, },
{ {
name: "allowed delete node CSINode - feature enabled", name: "allowed delete node CSINode - feature enabled",
attributes: admission.NewAttributesRecord(nil, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Delete, false, mynode), attributes: admission.NewAttributesRecord(nil, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Delete, &metav1.UpdateOptions{}, false, mynode),
features: csiNodeInfoEnabledFeature, features: csiNodeInfoEnabledFeature,
err: "", err: "",
}, },

View File

@@ -22,6 +22,7 @@ go_test(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/component-base/featuregate:go_default_library", "//staging/src/k8s.io/component-base/featuregate:go_default_library",

View File

@@ -21,6 +21,7 @@ import (
"testing" "testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"k8s.io/component-base/featuregate" "k8s.io/component-base/featuregate"
@@ -62,6 +63,7 @@ func Test_nodeTaints(t *testing.T) {
oldNode api.Node oldNode api.Node
features featuregate.FeatureGate features featuregate.FeatureGate
operation admission.Operation operation admission.Operation
options runtime.Object
expectedTaints []api.Taint expectedTaints []api.Taint
}{ }{
{ {
@@ -69,6 +71,7 @@ func Test_nodeTaints(t *testing.T) {
node: myNodeObj, node: myNodeObj,
features: enableTaintNodesByCondition, features: enableTaintNodesByCondition,
operation: admission.Create, operation: admission.Create,
options: &metav1.CreateOptions{},
expectedTaints: []api.Taint{notReadyTaint}, expectedTaints: []api.Taint{notReadyTaint},
}, },
{ {
@@ -76,6 +79,7 @@ func Test_nodeTaints(t *testing.T) {
node: myNodeObj, node: myNodeObj,
features: disableTaintNodesByCondition, features: disableTaintNodesByCondition,
operation: admission.Create, operation: admission.Create,
options: &metav1.CreateOptions{},
expectedTaints: nil, expectedTaints: nil,
}, },
{ {
@@ -83,6 +87,7 @@ func Test_nodeTaints(t *testing.T) {
node: myTaintedNodeObj, node: myTaintedNodeObj,
features: enableTaintNodesByCondition, features: enableTaintNodesByCondition,
operation: admission.Create, operation: admission.Create,
options: &metav1.CreateOptions{},
expectedTaints: []api.Taint{notReadyTaint}, expectedTaints: []api.Taint{notReadyTaint},
}, },
{ {
@@ -90,12 +95,13 @@ func Test_nodeTaints(t *testing.T) {
node: myUnreadyNodeObj, node: myUnreadyNodeObj,
features: enableTaintNodesByCondition, features: enableTaintNodesByCondition,
operation: admission.Create, operation: admission.Create,
options: &metav1.CreateOptions{},
expectedTaints: []api.Taint{notReadyTaint}, expectedTaints: []api.Taint{notReadyTaint},
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
attributes := admission.NewAttributesRecord(&tt.node, &tt.oldNode, nodeKind, myNodeObj.Namespace, myNodeObj.Name, resource, "", tt.operation, false, mynode) attributes := admission.NewAttributesRecord(&tt.node, &tt.oldNode, nodeKind, myNodeObj.Namespace, myNodeObj.Name, resource, "", tt.operation, tt.options, false, mynode)
c := NewPlugin() c := NewPlugin()
if tt.features != nil { if tt.features != nil {
c.features = tt.features c.features = tt.features

View File

@@ -161,7 +161,7 @@ func TestPodAdmission(t *testing.T) {
handler.clusterNodeSelectors[namespace.Name] = test.whitelist handler.clusterNodeSelectors[namespace.Name] = test.whitelist
pod.Spec = api.PodSpec{NodeSelector: test.podNodeSelector} pod.Spec = api.PodSpec{NodeSelector: test.podNodeSelector}
err := handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if test.admit && err != nil { if test.admit && err != nil {
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err) t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
} else if !test.admit && err == nil { } else if !test.admit && err == nil {
@@ -170,7 +170,7 @@ func TestPodAdmission(t *testing.T) {
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) { if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector) t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
} }
err = handler.Validate(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if test.admit && err != nil { if test.admit && err != nil {
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err) t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
} else if !test.admit && err == nil { } else if !test.admit && err == nil {

View File

@@ -819,6 +819,7 @@ func admitPod(pod *api.Pod, pip *settingsv1alpha1.PodPreset) error {
api.Resource("pods").WithVersion("version"), api.Resource("pods").WithVersion("version"),
"", "",
kadmission.Create, kadmission.Create,
&metav1.CreateOptions{},
false, false,
&user.DefaultInfo{}, &user.DefaultInfo{},
) )

View File

@@ -266,7 +266,7 @@ func TestPodAdmission(t *testing.T) {
pod := test.pod pod := test.pod
pod.Spec.Tolerations = test.podTolerations pod.Spec.Tolerations = test.podTolerations
err = handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if test.admit && err != nil { if test.admit && err != nil {
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err) t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
} else if !test.admit && err == nil { } else if !test.admit && err == nil {
@@ -343,7 +343,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) {
} }
// if the update of initialized pod is not ignored, an error will be returned because the pod's Tolerations conflicts with namespace's Tolerations. // if the update of initialized pod is not ignored, an error will be returned because the pod's Tolerations conflicts with namespace's Tolerations.
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", pod.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", pod.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("expected no error, got: %v", err) t.Errorf("expected no error, got: %v", err)
} }

View File

@@ -30,7 +30,7 @@ import (
featuregatetesting "k8s.io/component-base/featuregate/testing" featuregatetesting "k8s.io/component-base/featuregate/testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
"k8s.io/kubernetes/pkg/apis/scheduling/v1" v1 "k8s.io/kubernetes/pkg/apis/scheduling/v1"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
) )
@@ -155,6 +155,7 @@ func TestPriorityClassAdmission(t *testing.T) {
scheduling.Resource("priorityclasses").WithVersion("version"), scheduling.Resource("priorityclasses").WithVersion("version"),
"", "",
admission.Create, admission.Create,
&metav1.CreateOptions{},
false, false,
test.userInfo, test.userInfo,
) )
@@ -200,7 +201,7 @@ func TestDefaultPriority(t *testing.T) {
name: "add a default class", name: "add a default class",
classesBefore: []*scheduling.PriorityClass{nondefaultClass1}, classesBefore: []*scheduling.PriorityClass{nondefaultClass1},
classesAfter: []*scheduling.PriorityClass{nondefaultClass1, defaultClass1}, classesAfter: []*scheduling.PriorityClass{nondefaultClass1, defaultClass1},
attributes: admission.NewAttributesRecord(defaultClass1, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Create, false, nil), attributes: admission.NewAttributesRecord(defaultClass1, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Create, &metav1.CreateOptions{}, false, nil),
expectedDefaultBefore: scheduling.DefaultPriorityWhenNoDefaultClassExists, expectedDefaultBefore: scheduling.DefaultPriorityWhenNoDefaultClassExists,
expectedDefaultNameBefore: "", expectedDefaultNameBefore: "",
expectedDefaultAfter: defaultClass1.Value, expectedDefaultAfter: defaultClass1.Value,
@@ -210,7 +211,7 @@ func TestDefaultPriority(t *testing.T) {
name: "multiple default classes resolves to the minimum value among them", name: "multiple default classes resolves to the minimum value among them",
classesBefore: []*scheduling.PriorityClass{defaultClass1, defaultClass2}, classesBefore: []*scheduling.PriorityClass{defaultClass1, defaultClass2},
classesAfter: []*scheduling.PriorityClass{defaultClass2}, classesAfter: []*scheduling.PriorityClass{defaultClass2},
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, false, nil), attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, &metav1.DeleteOptions{}, false, nil),
expectedDefaultBefore: defaultClass1.Value, expectedDefaultBefore: defaultClass1.Value,
expectedDefaultNameBefore: defaultClass1.Name, expectedDefaultNameBefore: defaultClass1.Name,
expectedDefaultAfter: defaultClass2.Value, expectedDefaultAfter: defaultClass2.Value,
@@ -220,7 +221,7 @@ func TestDefaultPriority(t *testing.T) {
name: "delete default priority class", name: "delete default priority class",
classesBefore: []*scheduling.PriorityClass{defaultClass1}, classesBefore: []*scheduling.PriorityClass{defaultClass1},
classesAfter: []*scheduling.PriorityClass{}, classesAfter: []*scheduling.PriorityClass{},
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, false, nil), attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, &metav1.DeleteOptions{}, false, nil),
expectedDefaultBefore: defaultClass1.Value, expectedDefaultBefore: defaultClass1.Value,
expectedDefaultNameBefore: defaultClass1.Name, expectedDefaultNameBefore: defaultClass1.Name,
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists, expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
@@ -230,7 +231,7 @@ func TestDefaultPriority(t *testing.T) {
name: "update default class and remove its global default", name: "update default class and remove its global default",
classesBefore: []*scheduling.PriorityClass{defaultClass1}, classesBefore: []*scheduling.PriorityClass{defaultClass1},
classesAfter: []*scheduling.PriorityClass{&updatedDefaultClass1}, classesAfter: []*scheduling.PriorityClass{&updatedDefaultClass1},
attributes: admission.NewAttributesRecord(&updatedDefaultClass1, defaultClass1, pcKind, "", defaultClass1.Name, pcResource, "", admission.Update, false, nil), attributes: admission.NewAttributesRecord(&updatedDefaultClass1, defaultClass1, pcKind, "", defaultClass1.Name, pcResource, "", admission.Update, &metav1.UpdateOptions{}, false, nil),
expectedDefaultBefore: defaultClass1.Value, expectedDefaultBefore: defaultClass1.Value,
expectedDefaultNameBefore: defaultClass1.Name, expectedDefaultNameBefore: defaultClass1.Name,
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists, expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
@@ -600,6 +601,7 @@ func TestPodAdmission(t *testing.T) {
api.Resource("pods").WithVersion("version"), api.Resource("pods").WithVersion("version"),
"", "",
admission.Create, admission.Create,
&metav1.CreateOptions{},
false, false,
nil, nil,
) )

View File

@@ -153,7 +153,7 @@ func TestAdmissionIgnoresDelete(t *testing.T) {
evaluator: evaluator, evaluator: evaluator,
} }
namespace := "default" namespace := "default"
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", corev1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", corev1.Resource("pods").WithVersion("version"), "", admission.Delete, &metav1.DeleteOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("ResourceQuota should admit all deletes: %v", err) t.Errorf("ResourceQuota should admit all deletes: %v", err)
} }
@@ -190,11 +190,11 @@ func TestAdmissionIgnoresSubresources(t *testing.T) {
} }
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
newPod := validPod("123", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", ""))) newPod := validPod("123", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error because the pod exceeded allowed quota") t.Errorf("Expected an error because the pod exceeded allowed quota")
} }
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "subresource", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "subresource", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Did not expect an error because the action went to a subresource: %v", err) t.Errorf("Did not expect an error because the action went to a subresource: %v", err)
} }
@@ -235,7 +235,7 @@ func TestAdmitBelowQuotaLimit(t *testing.T) {
} }
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -318,13 +318,13 @@ func TestAdmitDryRun(t *testing.T) {
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, true, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, true, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
newPod = validPod("too-large-pod", 1, getResourceRequirements(getResourceList("100m", "60Gi"), getResourceList("", ""))) newPod = validPod("too-large-pod", 1, getResourceRequirements(getResourceList("100m", "60Gi"), getResourceList("", "")))
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, true, nil), nil) err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, true, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected error but got none") t.Errorf("Expected error but got none")
} }
@@ -384,7 +384,7 @@ func TestAdmitHandlesOldObjects(t *testing.T) {
Ports: []api.ServicePort{{Port: 1234}}, Ports: []api.ServicePort{{Port: 1234}},
}, },
} }
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -485,7 +485,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) {
}, },
} }
err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -544,7 +544,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) {
}, },
} }
err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -641,7 +641,7 @@ func TestAdmitHandlesCreatingUpdates(t *testing.T) {
Ports: []api.ServicePort{{Port: 1234}}, Ports: []api.ServicePort{{Port: 1234}},
}, },
} }
err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -724,7 +724,7 @@ func TestAdmitExceedQuotaLimit(t *testing.T) {
} }
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error exceeding quota") t.Errorf("Expected an error exceeding quota")
} }
@@ -770,7 +770,7 @@ func TestAdmitEnforceQuotaConstraints(t *testing.T) {
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
// verify all values are specified as required on the quota // verify all values are specified as required on the quota
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", ""))) newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error because the pod does not specify a memory limit") t.Errorf("Expected an error because the pod does not specify a memory limit")
} }
@@ -821,7 +821,7 @@ func TestAdmitPodInNamespaceWithoutQuota(t *testing.T) {
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", ""))) newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
// Add to the lru cache so we do not do a live client lookup // Add to the lru cache so we do not do a live client lookup
liveLookupCache.Add(newPod.Namespace, liveLookupEntry{expiry: time.Now().Add(time.Duration(30 * time.Second)), items: []*corev1.ResourceQuota{}}) liveLookupCache.Add(newPod.Namespace, liveLookupEntry{expiry: time.Now().Add(time.Duration(30 * time.Second)), items: []*corev1.ResourceQuota{}})
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Did not expect an error because the pod is in a different namespace than the quota") t.Errorf("Did not expect an error because the pod is in a different namespace than the quota")
} }
@@ -890,7 +890,7 @@ func TestAdmitBelowTerminatingQuotaLimit(t *testing.T) {
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
activeDeadlineSeconds := int64(30) activeDeadlineSeconds := int64(30)
newPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds newPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -994,7 +994,7 @@ func TestAdmitBelowBestEffortQuotaLimit(t *testing.T) {
// create a pod that is best effort because it does not make a request for anything // create a pod that is best effort because it does not make a request for anything
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -1084,7 +1084,7 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) {
} }
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "1Gi"), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "1Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -1193,7 +1193,7 @@ func TestAdmissionSetsMissingNamespace(t *testing.T) {
// unset the namespace // unset the namespace
newPod.ObjectMeta.Namespace = "" newPod.ObjectMeta.Namespace = ""
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Got unexpected error: %v", err) t.Errorf("Got unexpected error: %v", err)
} }
@@ -1236,14 +1236,14 @@ func TestAdmitRejectsNegativeUsage(t *testing.T) {
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
// verify quota rejects negative pvc storage requests // verify quota rejects negative pvc storage requests
newPvc := validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("-1Gi")}, api.ResourceList{})) newPvc := validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("-1Gi")}, api.ResourceList{}))
err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error because the pvc has negative storage usage") t.Errorf("Expected an error because the pvc has negative storage usage")
} }
// verify quota accepts non-negative pvc storage requests // verify quota accepts non-negative pvc storage requests
newPvc = validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("1Gi")}, api.ResourceList{})) newPvc = validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("1Gi")}, api.ResourceList{}))
err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -1284,7 +1284,7 @@ func TestAdmitWhenUnrelatedResourceExceedsQuota(t *testing.T) {
// create a pod that should pass existing quota // create a pod that should pass existing quota
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -1318,7 +1318,7 @@ func TestAdmitLimitedResourceNoQuota(t *testing.T) {
evaluator: evaluator, evaluator: evaluator,
} }
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error for consuming a limited resource without quota.") t.Errorf("Expected an error for consuming a limited resource without quota.")
} }
@@ -1352,7 +1352,7 @@ func TestAdmitLimitedResourceNoQuotaIgnoresNonMatchingResources(t *testing.T) {
evaluator: evaluator, evaluator: evaluator,
} }
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@@ -1400,7 +1400,7 @@ func TestAdmitLimitedResourceWithQuota(t *testing.T) {
} }
indexer.Add(resourceQuota) indexer.Add(resourceQuota)
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -1460,7 +1460,7 @@ func TestAdmitLimitedResourceWithMultipleQuota(t *testing.T) {
indexer.Add(resourceQuota1) indexer.Add(resourceQuota1)
indexer.Add(resourceQuota2) indexer.Add(resourceQuota2)
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -1508,7 +1508,7 @@ func TestAdmitLimitedResourceWithQuotaThatDoesNotCover(t *testing.T) {
} }
indexer.Add(resourceQuota) indexer.Add(resourceQuota)
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Fatalf("Expected an error since the quota did not cover cpu") t.Fatalf("Expected an error since the quota did not cover cpu")
} }
@@ -2169,7 +2169,7 @@ func TestAdmitLimitedScopeWithCoverQuota(t *testing.T) {
if testCase.anotherQuota != nil { if testCase.anotherQuota != nil {
indexer.Add(testCase.anotherQuota) indexer.Add(testCase.anotherQuota)
} }
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if testCase.expErr == "" { if testCase.expErr == "" {
if err != nil { if err != nil {
t.Fatalf("Testcase, %v, failed with unexpected error: %v. ExpErr: %v", testCase.description, err, testCase.expErr) t.Fatalf("Testcase, %v, failed with unexpected error: %v. ExpErr: %v", testCase.description, err, testCase.expErr)
@@ -2221,7 +2221,7 @@ func TestAdmitZeroDeltaUsageWithoutCoveringQuota(t *testing.T) {
Spec: api.ServiceSpec{Type: api.ServiceTypeLoadBalancer}, Spec: api.ServiceSpec{Type: api.ServiceTypeLoadBalancer},
} }
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -2267,7 +2267,7 @@ func TestAdmitRejectIncreaseUsageWithoutCoveringQuota(t *testing.T) {
Spec: api.ServiceSpec{Type: api.ServiceTypeLoadBalancer}, Spec: api.ServiceSpec{Type: api.ServiceTypeLoadBalancer},
} }
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error for consuming a limited resource without quota.") t.Errorf("Expected an error for consuming a limited resource without quota.")
} }
@@ -2313,7 +2313,7 @@ func TestAdmitAllowDecreaseUsageWithoutCoveringQuota(t *testing.T) {
}, },
} }
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Expected no error for decreasing a limited resource without quota, got %v", err) t.Errorf("Expected no error for decreasing a limited resource without quota, got %v", err)
} }

View File

@@ -24,7 +24,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
policy "k8s.io/api/policy/v1beta1" policy "k8s.io/api/policy/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -473,7 +473,7 @@ func TestAdmitPreferNonmutating(t *testing.T) {
func TestFailClosedOnInvalidPod(t *testing.T) { func TestFailClosedOnInvalidPod(t *testing.T) {
plugin := NewTestAdmission(nil, nil) plugin := NewTestAdmission(nil, nil)
pod := &v1.Pod{} pod := &v1.Pod{}
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, false, &user.DefaultInfo{}) attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
err := plugin.Admit(attrs, nil) err := plugin.Admit(attrs, nil)
if err == nil { if err == nil {
@@ -1776,7 +1776,7 @@ func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*
originalPod := pod.DeepCopy() originalPod := pod.DeepCopy()
plugin := NewTestAdmission(psps, authz) plugin := NewTestAdmission(psps, authz)
attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, false, userInfo) attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, nil, false, userInfo)
annotations := make(map[string]string) annotations := make(map[string]string)
attrs = &fakeAttributes{attrs, annotations} attrs = &fakeAttributes{attrs, annotations}
err := plugin.Admit(attrs, nil) err := plugin.Admit(attrs, nil)
@@ -2240,7 +2240,7 @@ func TestPolicyAuthorizationErrors(t *testing.T) {
pod.Spec.SecurityContext.HostPID = true pod.Spec.SecurityContext.HostPID = true
plugin := NewTestAdmission(tc.inPolicies, authz) plugin := NewTestAdmission(tc.inPolicies, authz)
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, false, &user.DefaultInfo{Name: userName}) attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{Name: userName})
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true, "") allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true, "")
assert.Nil(t, allowedPod) assert.Nil(t, allowedPod)
@@ -2333,7 +2333,7 @@ func TestPreferValidatedPSP(t *testing.T) {
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation
plugin := NewTestAdmission(tc.inPolicies, authz) plugin := NewTestAdmission(tc.inPolicies, authz)
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, false, &user.DefaultInfo{Name: "test"}) attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, &metav1.UpdateOptions{}, false, &user.DefaultInfo{Name: "test"})
_, pspName, validationErrs, err := plugin.computeSecurityContext(attrs, pod, false, tc.validatedPSPHint) _, pspName, validationErrs, err := plugin.computeSecurityContext(attrs, pod, false, tc.validatedPSPHint)
assert.NoError(t, err) assert.NoError(t, err)

View File

@@ -82,7 +82,7 @@ func TestAdmission(t *testing.T) {
p.Spec.SecurityContext = tc.podSc p.Spec.SecurityContext = tc.podSc
p.Spec.Containers[0].SecurityContext = tc.sc p.Spec.Containers[0].SecurityContext = tc.sc
err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil, false, nil), nil)
if err != nil && !tc.expectError { if err != nil && !tc.expectError {
t.Errorf("%v: unexpected error: %v", tc.name, err) t.Errorf("%v: unexpected error: %v", tc.name, err)
} else if err == nil && tc.expectError { } else if err == nil && tc.expectError {
@@ -96,7 +96,7 @@ func TestAdmission(t *testing.T) {
p.Spec.InitContainers = p.Spec.Containers p.Spec.InitContainers = p.Spec.Containers
p.Spec.Containers = nil p.Spec.Containers = nil
err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil) err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil, false, nil), nil)
if err != nil && !tc.expectError { if err != nil && !tc.expectError {
t.Errorf("%v: unexpected error: %v", tc.name, err) t.Errorf("%v: unexpected error: %v", tc.name, err)
} else if err == nil && tc.expectError { } else if err == nil && tc.expectError {
@@ -140,7 +140,7 @@ func TestPodSecurityContextAdmission(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
pod.Spec.SecurityContext = &test.securityContext pod.Spec.SecurityContext = &test.securityContext
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil) err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil, false, nil), nil)
if test.errorExpected && err == nil { if test.errorExpected && err == nil {
t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext) t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext)

View File

@@ -64,7 +64,7 @@ func TestIgnoresNonCreate(t *testing.T) {
func TestIgnoresNonPodResource(t *testing.T) { func TestIgnoresNonPodResource(t *testing.T) {
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("CustomResource").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("CustomResource").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := NewServiceAccount().Admit(attrs, nil) err := NewServiceAccount().Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Expected non-pod resource allowed, got err: %v", err) t.Errorf("Expected non-pod resource allowed, got err: %v", err)
@@ -72,7 +72,7 @@ func TestIgnoresNonPodResource(t *testing.T) {
} }
func TestIgnoresNilObject(t *testing.T) { func TestIgnoresNilObject(t *testing.T) {
attrs := admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := NewServiceAccount().Admit(attrs, nil) err := NewServiceAccount().Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Expected nil object allowed allowed, got err: %v", err) t.Errorf("Expected nil object allowed allowed, got err: %v", err)
@@ -81,7 +81,7 @@ func TestIgnoresNilObject(t *testing.T) {
func TestIgnoresNonPodObject(t *testing.T) { func TestIgnoresNonPodObject(t *testing.T) {
obj := &api.Namespace{} obj := &api.Namespace{}
attrs := admission.NewAttributesRecord(obj, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(obj, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := NewServiceAccount().Admit(attrs, nil) err := NewServiceAccount().Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Expected non pod object allowed, got err: %v", err) t.Errorf("Expected non pod object allowed, got err: %v", err)
@@ -101,7 +101,7 @@ func TestIgnoresMirrorPod(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := NewServiceAccount().Admit(attrs, nil) err := NewServiceAccount().Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Expected mirror pod without service account or secrets allowed, got err: %v", err) t.Errorf("Expected mirror pod without service account or secrets allowed, got err: %v", err)
@@ -119,7 +119,7 @@ func TestRejectsMirrorPodWithServiceAccount(t *testing.T) {
ServiceAccountName: "default", ServiceAccountName: "default",
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := NewServiceAccount().Admit(attrs, nil) err := NewServiceAccount().Admit(attrs, nil)
if err == nil { if err == nil {
t.Errorf("Expected a mirror pod to be prevented from referencing a service account") t.Errorf("Expected a mirror pod to be prevented from referencing a service account")
@@ -139,7 +139,7 @@ func TestRejectsMirrorPodWithSecretVolumes(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := NewServiceAccount().Admit(attrs, nil) err := NewServiceAccount().Admit(attrs, nil)
if err == nil { if err == nil {
t.Errorf("Expected a mirror pod to be prevented from referencing a secret volume") t.Errorf("Expected a mirror pod to be prevented from referencing a secret volume")
@@ -164,7 +164,7 @@ func TestRejectsMirrorPodWithServiceAccountTokenVolumeProjections(t *testing.T)
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := NewServiceAccount().Admit(attrs, nil) err := NewServiceAccount().Admit(attrs, nil)
if err == nil { if err == nil {
t.Errorf("Expected a mirror pod to be prevented from referencing a ServiceAccountToken volume projection") t.Errorf("Expected a mirror pod to be prevented from referencing a ServiceAccountToken volume projection")
@@ -189,7 +189,7 @@ func TestAssignsDefaultServiceAccountAndToleratesMissingAPIToken(t *testing.T) {
}) })
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@@ -217,7 +217,7 @@ func TestAssignsDefaultServiceAccountAndRejectsMissingAPIToken(t *testing.T) {
}) })
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err == nil || !errors.IsServerTimeout(err) { if err == nil || !errors.IsServerTimeout(err) {
t.Errorf("Expected server timeout error for missing API token: %v", err) t.Errorf("Expected server timeout error for missing API token: %v", err)
@@ -242,7 +242,7 @@ func TestFetchesUncachedServiceAccount(t *testing.T) {
admit.RequireAPIToken = false admit.RequireAPIToken = false
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@@ -264,7 +264,7 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
admit.SetExternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err == nil { if err == nil {
t.Errorf("Expected error for missing service account, got none") t.Errorf("Expected error for missing service account, got none")
@@ -330,7 +330,7 @@ func TestAutomountsAPIToken(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@@ -359,7 +359,7 @@ func TestAutomountsAPIToken(t *testing.T) {
}, },
}, },
} }
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err != nil { if err := admit.Admit(attrs, nil); err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -441,7 +441,7 @@ func TestRespectsExistingMount(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@@ -471,7 +471,7 @@ func TestRespectsExistingMount(t *testing.T) {
}, },
}, },
} }
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err != nil { if err := admit.Admit(attrs, nil); err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -517,7 +517,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err != nil { if err := admit.Admit(attrs, nil); err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -541,7 +541,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
}, },
}, },
} }
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err != nil { if err := admit.Admit(attrs, nil); err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -565,7 +565,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
}, },
}, },
} }
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err != nil { if err := admit.Admit(attrs, nil); err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -595,7 +595,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err == nil { if err := admit.Admit(attrs, nil); err == nil {
t.Errorf("Expected rejection for using a secret the service account does not reference") t.Errorf("Expected rejection for using a secret the service account does not reference")
} }
@@ -619,7 +619,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
}, },
}, },
} }
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") { if err := admit.Admit(attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -643,7 +643,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
}, },
}, },
} }
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") { if err := admit.Admit(attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -674,7 +674,7 @@ func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err == nil { if err == nil {
t.Errorf("Expected rejection for using a secret the service account does not reference") t.Errorf("Expected rejection for using a secret the service account does not reference")
@@ -706,7 +706,7 @@ func TestAllowsReferencedImagePullSecrets(t *testing.T) {
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}}, ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@@ -735,7 +735,7 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) {
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}}, ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err == nil { if err == nil {
t.Errorf("Expected rejection for using a secret the service account does not reference") t.Errorf("Expected rejection for using a secret the service account does not reference")
@@ -768,7 +768,7 @@ func TestDoNotAddImagePullSecrets(t *testing.T) {
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}}, ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@@ -802,7 +802,7 @@ func TestAddImagePullSecrets(t *testing.T) {
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(sa) informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(sa)
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@@ -883,7 +883,7 @@ func TestMultipleReferencedSecrets(t *testing.T) {
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
if err := admit.Admit(attrs, nil); err != nil { if err := admit.Admit(attrs, nil); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -1037,7 +1037,7 @@ func TestAutomountIsBackwardsCompatible(t *testing.T) {
}, },
}, },
} }
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
err := admit.Admit(attrs, nil) err := admit.Admit(attrs, nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)

View File

@@ -23,7 +23,7 @@ import (
"sort" "sort"
"testing" "testing"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
@@ -756,7 +756,7 @@ func Test_PVLAdmission(t *testing.T) {
setPVLabeler(testcase.handler, testcase.pvlabeler) setPVLabeler(testcase.handler, testcase.pvlabeler)
handler := admission.NewChainHandler(testcase.handler) handler := admission.NewChainHandler(testcase.handler)
err := handler.Admit(admission.NewAttributesRecord(testcase.preAdmissionPV, nil, api.Kind("PersistentVolume").WithVersion("version"), testcase.preAdmissionPV.Namespace, testcase.preAdmissionPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil), nil) err := handler.Admit(admission.NewAttributesRecord(testcase.preAdmissionPV, nil, api.Kind("PersistentVolume").WithVersion("version"), testcase.preAdmissionPV.Namespace, testcase.preAdmissionPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if !reflect.DeepEqual(err, testcase.err) { if !reflect.DeepEqual(err, testcase.err) {
t.Logf("expected error: %q", testcase.err) t.Logf("expected error: %q", testcase.err)
t.Logf("actual error: %q", err) t.Logf("actual error: %q", err)

View File

@@ -254,7 +254,8 @@ func TestPVCResizeAdmission(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
operation := admission.Update operation := admission.Update
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, nil) operationOptions := &metav1.CreateOptions{}
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, operationOptions, false, nil)
err := ctrl.Validate(attributes, nil) err := ctrl.Validate(attributes, nil)
if !tc.checkError(err) { if !tc.checkError(err) {

View File

@@ -208,6 +208,7 @@ func TestAdmission(t *testing.T) {
api.Resource("persistentvolumeclaims").WithVersion("version"), api.Resource("persistentvolumeclaims").WithVersion("version"),
"", // subresource "", // subresource
admission.Create, admission.Create,
&metav1.CreateOptions{},
false, // dryRun false, // dryRun
nil, // userInfo nil, // userInfo
) )

View File

@@ -131,6 +131,7 @@ func TestAdmit(t *testing.T) {
test.resource, test.resource,
"", // subresource "", // subresource
admission.Create, admission.Create,
&metav1.CreateOptions{},
false, // dryRun false, // dryRun
nil, // userInfo nil, // userInfo
) )

View File

@@ -64,7 +64,7 @@ func (h fakeHandler) Handles(o Operation) bool {
} }
func attributes() Attributes { func attributes() Attributes {
return NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", "", false, nil) return NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", "", nil, false, nil)
} }
func TestWithAudit(t *testing.T) { func TestWithAudit(t *testing.T) {

View File

@@ -21,6 +21,7 @@ import (
"testing" "testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
) )
@@ -63,6 +64,7 @@ func TestAdmitAndValidate(t *testing.T) {
name string name string
ns string ns string
operation Operation operation Operation
options runtime.Object
chain chainAdmissionHandler chain chainAdmissionHandler
accept bool accept bool
calls map[string]bool calls map[string]bool
@@ -71,6 +73,7 @@ func TestAdmitAndValidate(t *testing.T) {
name: "all accept", name: "all accept",
ns: sysns, ns: sysns,
operation: Create, operation: Create,
options: &metav1.CreateOptions{},
chain: []Interface{ chain: []Interface{
makeHandler("a", true, Update, Delete, Create), makeHandler("a", true, Update, Delete, Create),
makeHandler("b", true, Delete, Create), makeHandler("b", true, Delete, Create),
@@ -83,6 +86,7 @@ func TestAdmitAndValidate(t *testing.T) {
name: "ignore handler", name: "ignore handler",
ns: otherns, ns: otherns,
operation: Create, operation: Create,
options: &metav1.CreateOptions{},
chain: []Interface{ chain: []Interface{
makeHandler("a", true, Update, Delete, Create), makeHandler("a", true, Update, Delete, Create),
makeHandler("b", false, Delete), makeHandler("b", false, Delete),
@@ -95,6 +99,7 @@ func TestAdmitAndValidate(t *testing.T) {
name: "ignore all", name: "ignore all",
ns: sysns, ns: sysns,
operation: Connect, operation: Connect,
options: nil,
chain: []Interface{ chain: []Interface{
makeHandler("a", true, Update, Delete, Create), makeHandler("a", true, Update, Delete, Create),
makeHandler("b", false, Delete), makeHandler("b", false, Delete),
@@ -107,6 +112,7 @@ func TestAdmitAndValidate(t *testing.T) {
name: "reject one", name: "reject one",
ns: otherns, ns: otherns,
operation: Delete, operation: Delete,
options: &metav1.DeleteOptions{},
chain: []Interface{ chain: []Interface{
makeHandler("a", true, Update, Delete, Create), makeHandler("a", true, Update, Delete, Create),
makeHandler("b", false, Delete), makeHandler("b", false, Delete),
@@ -119,7 +125,7 @@ func TestAdmitAndValidate(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Logf("testcase = %s", test.name) t.Logf("testcase = %s", test.name)
// call admit and check that validate was not called at all // call admit and check that validate was not called at all
err := test.chain.Admit(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil) err := test.chain.Admit(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, test.options, false, nil), nil)
accepted := (err == nil) accepted := (err == nil)
if accepted != test.accept { if accepted != test.accept {
t.Errorf("unexpected result of admit call: %v", accepted) t.Errorf("unexpected result of admit call: %v", accepted)
@@ -140,7 +146,7 @@ func TestAdmitAndValidate(t *testing.T) {
} }
// call validate and check that admit was not called at all // call validate and check that admit was not called at all
err = test.chain.Validate(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil) err = test.chain.Validate(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, test.options, false, nil), nil)
accepted = (err == nil) accepted = (err == nil)
if accepted != test.accept { if accepted != test.accept {
t.Errorf("unexpected result of validate call: %v\n", accepted) t.Errorf("unexpected result of validate call: %v\n", accepted)

View File

@@ -36,6 +36,7 @@ func TestNewForbidden(t *testing.T) {
schema.GroupVersionResource{Group: "foo", Version: "bar", Resource: "baz"}, schema.GroupVersionResource{Group: "foo", Version: "bar", Resource: "baz"},
"", "",
Create, Create,
nil,
false, false,
nil) nil)
err := errors.New("some error") err := errors.New("some error")

View File

@@ -20,6 +20,8 @@ go_test(
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",

View File

@@ -21,6 +21,8 @@ import (
"testing" "testing"
"time" "time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
) )
@@ -28,7 +30,7 @@ import (
var ( var (
kind = schema.GroupVersionKind{Group: "kgroup", Version: "kversion", Kind: "kind"} kind = schema.GroupVersionKind{Group: "kgroup", Version: "kversion", Kind: "kind"}
resource = schema.GroupVersionResource{Group: "rgroup", Version: "rversion", Resource: "resource"} resource = schema.GroupVersionResource{Group: "rgroup", Version: "rversion", Resource: "resource"}
attr = admission.NewAttributesRecord(nil, nil, kind, "ns", "name", resource, "subresource", admission.Create, false, nil) attr = admission.NewAttributesRecord(nil, nil, kind, "ns", "name", resource, "subresource", admission.Create, &metav1.CreateOptions{}, false, nil)
) )
func TestObserveAdmissionStep(t *testing.T) { func TestObserveAdmissionStep(t *testing.T) {
@@ -85,6 +87,7 @@ func TestWithMetrics(t *testing.T) {
name string name string
ns string ns string
operation admission.Operation operation admission.Operation
options runtime.Object
handler admission.Interface handler admission.Interface
admit, validate bool admit, validate bool
} }
@@ -93,6 +96,7 @@ func TestWithMetrics(t *testing.T) {
"both-interfaces-admit-and-validate", "both-interfaces-admit-and-validate",
"some-ns", "some-ns",
admission.Create, admission.Create,
&metav1.CreateOptions{},
&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true, true}, &mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true, true},
true, true, true, true,
}, },
@@ -100,6 +104,7 @@ func TestWithMetrics(t *testing.T) {
"both-interfaces-dont-admit", "both-interfaces-dont-admit",
"some-ns", "some-ns",
admission.Create, admission.Create,
&metav1.CreateOptions{},
&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false, true}, &mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false, true},
false, true, false, true,
}, },
@@ -107,6 +112,7 @@ func TestWithMetrics(t *testing.T) {
"both-interfaces-admit-dont-validate", "both-interfaces-admit-dont-validate",
"some-ns", "some-ns",
admission.Create, admission.Create,
&metav1.CreateOptions{},
&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true, false}, &mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true, false},
true, false, true, false,
}, },
@@ -114,6 +120,7 @@ func TestWithMetrics(t *testing.T) {
"validate-interfaces-validate", "validate-interfaces-validate",
"some-ns", "some-ns",
admission.Create, admission.Create,
&metav1.CreateOptions{},
&validatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true}, &validatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true},
true, true, true, true,
}, },
@@ -121,6 +128,7 @@ func TestWithMetrics(t *testing.T) {
"validate-interfaces-dont-validate", "validate-interfaces-dont-validate",
"some-ns", "some-ns",
admission.Create, admission.Create,
&metav1.CreateOptions{},
&validatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false}, &validatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false},
true, false, true, false,
}, },
@@ -128,6 +136,7 @@ func TestWithMetrics(t *testing.T) {
"mutating-interfaces-admit", "mutating-interfaces-admit",
"some-ns", "some-ns",
admission.Create, admission.Create,
&metav1.CreateOptions{},
&mutatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true}, &mutatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true},
true, true, true, true,
}, },
@@ -135,6 +144,7 @@ func TestWithMetrics(t *testing.T) {
"mutating-interfaces-dont-admit", "mutating-interfaces-dont-admit",
"some-ns", "some-ns",
admission.Create, admission.Create,
&metav1.CreateOptions{},
&mutatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false}, &mutatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false},
false, true, false, true,
}, },
@@ -144,7 +154,7 @@ func TestWithMetrics(t *testing.T) {
h := WithMetrics(test.handler, Metrics.ObserveAdmissionController, test.name) h := WithMetrics(test.handler, Metrics.ObserveAdmissionController, test.name)
// test mutation // test mutation
err := h.(admission.MutationInterface).Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil) err := h.(admission.MutationInterface).Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, test.options, false, nil), nil)
if test.admit && err != nil { if test.admit && err != nil {
t.Errorf("expected admit to succeed, but failed: %v", err) t.Errorf("expected admit to succeed, but failed: %v", err)
continue continue
@@ -169,7 +179,7 @@ func TestWithMetrics(t *testing.T) {
} }
// test validation // test validation
err = h.(admission.ValidationInterface).Validate(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil) err = h.(admission.ValidationInterface).Validate(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, test.options, false, nil), nil)
if test.validate && err != nil { if test.validate && err != nil {
t.Errorf("expected admit to succeed, but failed: %v", err) t.Errorf("expected admit to succeed, but failed: %v", err)
continue continue

View File

@@ -21,7 +21,7 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
@@ -104,7 +104,7 @@ func TestAccessReviewCheckOnMissingNamespace(t *testing.T) {
} }
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
err = handler.Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "LocalSubjectAccesReview"}, namespace, "", schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "localsubjectaccessreviews"}, "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "LocalSubjectAccesReview"}, namespace, "", schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "localsubjectaccessreviews"}, "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@@ -124,7 +124,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
actions := "" actions := ""
for _, action := range mockClient.Actions() { for _, action := range mockClient.Actions() {
@@ -134,19 +134,19 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
} }
// verify create operations in the namespace cause an error // verify create operations in the namespace cause an error
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected error rejecting creates in a namespace when it is missing") t.Errorf("Expected error rejecting creates in a namespace when it is missing")
} }
// verify update operations in the namespace cause an error // verify update operations in the namespace cause an error
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected error rejecting updates in a namespace when it is missing") t.Errorf("Expected error rejecting updates in a namespace when it is missing")
} }
// verify delete operations in the namespace can proceed // verify delete operations in the namespace can proceed
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, &metav1.DeleteOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err) t.Errorf("Unexpected error returned from admission handler: %v", err)
} }
@@ -166,7 +166,7 @@ func TestAdmissionNamespaceActive(t *testing.T) {
informerFactory.Start(wait.NeverStop) informerFactory.Start(wait.NeverStop)
pod := newPod(namespace) pod := newPod(namespace)
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("unexpected error returned from admission handler") t.Errorf("unexpected error returned from admission handler")
} }
@@ -187,31 +187,31 @@ func TestAdmissionNamespaceTerminating(t *testing.T) {
pod := newPod(namespace) pod := newPod(namespace)
// verify create operations in the namespace cause an error // verify create operations in the namespace cause an error
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected error rejecting creates in a namespace when it is terminating") t.Errorf("Expected error rejecting creates in a namespace when it is terminating")
} }
// verify update operations in the namespace can proceed // verify update operations in the namespace can proceed
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err) t.Errorf("Unexpected error returned from admission handler: %v", err)
} }
// verify delete operations in the namespace can proceed // verify delete operations in the namespace can proceed
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, &metav1.DeleteOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err) t.Errorf("Unexpected error returned from admission handler: %v", err)
} }
// verify delete of namespace default can never proceed // verify delete of namespace default can never proceed
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", metav1.NamespaceDefault, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", metav1.NamespaceDefault, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, &metav1.DeleteOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected an error that this namespace can never be deleted") t.Errorf("Expected an error that this namespace can never be deleted")
} }
// verify delete of namespace other than default can proceed // verify delete of namespace other than default can proceed
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", "other", v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", "other", v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, &metav1.DeleteOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Did not expect an error %v", err) t.Errorf("Did not expect an error %v", err)
} }
@@ -238,7 +238,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
pod := newPod(namespace) pod := newPod(namespace)
// verify create operations in the namespace is allowed // verify create operations in the namespace is allowed
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Unexpected error rejecting creates in an active namespace") t.Errorf("Unexpected error rejecting creates in an active namespace")
} }
@@ -248,7 +248,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
getCalls = 0 getCalls = 0
// verify delete of namespace can proceed // verify delete of namespace can proceed
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), namespace, namespace, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), namespace, namespace, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, &metav1.DeleteOptions{}, false, nil), nil)
if err != nil { if err != nil {
t.Errorf("Expected namespace deletion to be allowed") t.Errorf("Expected namespace deletion to be allowed")
} }
@@ -261,7 +261,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
phases[namespace] = v1.NamespaceTerminating phases[namespace] = v1.NamespaceTerminating
// verify create operations in the namespace cause an error // verify create operations in the namespace cause an error
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected error rejecting creates in a namespace right after deleting it") t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
} }
@@ -274,7 +274,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
fakeClock.Step(forceLiveLookupTTL) fakeClock.Step(forceLiveLookupTTL)
// verify create operations in the namespace cause an error // verify create operations in the namespace cause an error
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if err == nil { if err == nil {
t.Errorf("Expected error rejecting creates in a namespace right after deleting it") t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
} }
@@ -287,7 +287,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
fakeClock.Step(time.Millisecond) fakeClock.Step(time.Millisecond)
// verify create operations in the namespace don't force a live lookup after the timeout // verify create operations in the namespace don't force a live lookup after the timeout
handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil) handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil), nil)
if getCalls != 0 { if getCalls != 0 {
t.Errorf("Expected no live lookup of the namespace at t=forceLiveLookupTTL+1ms, got %d", getCalls) t.Errorf("Expected no live lookup of the namespace at t=forceLiveLookupTTL+1ms, got %d", getCalls)
} }

View File

@@ -122,7 +122,7 @@ func TestDispatch(t *testing.T) {
plugin: &Plugin{}, plugin: &Plugin{},
} }
attr := generic.VersionedAttributes{ attr := generic.VersionedAttributes{
Attributes: admission.NewAttributesRecord(test.out, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", admission.Operation(""), false, nil), Attributes: admission.NewAttributesRecord(test.out, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", admission.Operation(""), nil, false, nil),
VersionedOldObject: nil, VersionedOldObject: nil,
VersionedObject: test.in, VersionedObject: test.in,
} }

View File

@@ -75,27 +75,27 @@ func TestGetNamespaceLabels(t *testing.T) {
}{ }{
{ {
name: "request is for creating namespace, the labels should be from the object itself", name: "request is for creating namespace, the labels should be from the object itself",
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, "", namespace2.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Create, false, nil), attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, "", namespace2.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Create, &metav1.CreateOptions{}, false, nil),
expectedLabels: namespace2Labels, expectedLabels: namespace2Labels,
}, },
{ {
name: "request is for updating namespace, the labels should be from the new object", name: "request is for updating namespace, the labels should be from the new object",
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace2.Name, namespace2.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Update, false, nil), attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace2.Name, namespace2.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Update, &metav1.UpdateOptions{}, false, nil),
expectedLabels: namespace2Labels, expectedLabels: namespace2Labels,
}, },
{ {
name: "request is for deleting namespace, the labels should be from the cache", name: "request is for deleting namespace, the labels should be from the cache",
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace1.Name, namespace1.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Delete, false, nil), attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace1.Name, namespace1.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Delete, &metav1.DeleteOptions{}, false, nil),
expectedLabels: namespace1Labels, expectedLabels: namespace1Labels,
}, },
{ {
name: "request is for namespace/finalizer", name: "request is for namespace/finalizer",
attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "namespaces"}, "finalizers", admission.Create, false, nil), attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "namespaces"}, "finalizers", admission.Create, &metav1.CreateOptions{}, false, nil),
expectedLabels: namespace1Labels, expectedLabels: namespace1Labels,
}, },
{ {
name: "request is for pod", name: "request is for pod",
attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "pods"}, "", admission.Create, false, nil), attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "pods"}, "", admission.Create, &metav1.CreateOptions{}, false, nil),
expectedLabels: namespace1Labels, expectedLabels: namespace1Labels,
}, },
} }
@@ -117,7 +117,7 @@ func TestNotExemptClusterScopedResource(t *testing.T) {
hook := &registrationv1beta1.Webhook{ hook := &registrationv1beta1.Webhook{
NamespaceSelector: &metav1.LabelSelector{}, NamespaceSelector: &metav1.LabelSelector{},
} }
attr := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "mock-name", schema.GroupVersionResource{Version: "v1", Resource: "nodes"}, "", admission.Create, false, nil) attr := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "mock-name", schema.GroupVersionResource{Version: "v1", Resource: "nodes"}, "", admission.Create, &metav1.CreateOptions{}, false, nil)
matcher := Matcher{} matcher := Matcher{}
matches, err := matcher.MatchNamespaceSelector(hook, attr) matches, err := matcher.MatchNamespaceSelector(hook, attr)
if err != nil { if err != nil {

View File

@@ -20,6 +20,8 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library", "//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",

View File

@@ -21,6 +21,8 @@ import (
"testing" "testing"
adreg "k8s.io/api/admissionregistration/v1beta1" adreg "k8s.io/api/admissionregistration/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
@@ -33,37 +35,40 @@ type ruleTest struct {
} }
type tests map[string]ruleTest type tests map[string]ruleTest
func a(group, version, resource, subresource, name string, operation admission.Operation) admission.Attributes { func a(group, version, resource, subresource, name string, operation admission.Operation, operationOptions runtime.Object) admission.Attributes {
return admission.NewAttributesRecord( return admission.NewAttributesRecord(
nil, nil, nil, nil,
schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource}, schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource},
"ns", name, "ns", name,
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource, schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
operation, operation,
operationOptions,
false, false,
nil, nil,
) )
} }
func namespacedAttributes(group, version, resource, subresource, name string, operation admission.Operation) admission.Attributes { func namespacedAttributes(group, version, resource, subresource, name string, operation admission.Operation, operationOptions runtime.Object) admission.Attributes {
return admission.NewAttributesRecord( return admission.NewAttributesRecord(
nil, nil, nil, nil,
schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource}, schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource},
"ns", name, "ns", name,
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource, schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
operation, operation,
operationOptions,
false, false,
nil, nil,
) )
} }
func clusterScopedAttributes(group, version, resource, subresource, name string, operation admission.Operation) admission.Attributes { func clusterScopedAttributes(group, version, resource, subresource, name string, operation admission.Operation, operationOptions runtime.Object) admission.Attributes {
return admission.NewAttributesRecord( return admission.NewAttributesRecord(
nil, nil, nil, nil,
schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource}, schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource},
"", name, "", name,
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource, schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
operation, operation,
operationOptions,
false, false,
nil, nil,
) )
@@ -82,7 +87,7 @@ func TestGroup(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
"exact": { "exact": {
@@ -92,12 +97,12 @@ func TestGroup(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g1", "v", "r", "", "name", admission.Create), a("g1", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g2", "v2", "r3", "", "name", admission.Create), a("g2", "v2", "r3", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g3", "v", "r", "", "name", admission.Create), a("g3", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g4", "v", "r", "", "name", admission.Create), a("g4", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
} }
@@ -127,7 +132,7 @@ func TestVersion(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
"exact": { "exact": {
@@ -137,12 +142,12 @@ func TestVersion(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g1", "v1", "r", "", "name", admission.Create), a("g1", "v1", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g2", "v2", "r", "", "name", admission.Create), a("g2", "v2", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g1", "v3", "r", "", "name", admission.Create), a("g1", "v3", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g2", "v4", "r", "", "name", admission.Create), a("g2", "v4", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
} }
@@ -167,65 +172,65 @@ func TestOperation(t *testing.T) {
"wildcard": { "wildcard": {
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.OperationAll}}, rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.OperationAll}},
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g", "v", "r", "", "name", admission.Update), a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
a("g", "v", "r", "", "name", admission.Delete), a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
a("g", "v", "r", "", "name", admission.Connect), a("g", "v", "r", "", "name", admission.Connect, nil),
), ),
}, },
"create": { "create": {
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Create}}, rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Create}},
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g", "v", "r", "", "name", admission.Update), a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
a("g", "v", "r", "", "name", admission.Delete), a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
a("g", "v", "r", "", "name", admission.Connect), a("g", "v", "r", "", "name", admission.Connect, nil),
), ),
}, },
"update": { "update": {
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Update}}, rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Update}},
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Update), a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g", "v", "r", "", "name", admission.Delete), a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
a("g", "v", "r", "", "name", admission.Connect), a("g", "v", "r", "", "name", admission.Connect, nil),
), ),
}, },
"delete": { "delete": {
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Delete}}, rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Delete}},
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Delete), a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g", "v", "r", "", "name", admission.Update), a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
a("g", "v", "r", "", "name", admission.Connect), a("g", "v", "r", "", "name", admission.Connect, nil),
), ),
}, },
"connect": { "connect": {
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Connect}}, rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Connect}},
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Connect), a("g", "v", "r", "", "name", admission.Connect, nil),
), ),
noMatch: attrList( noMatch: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g", "v", "r", "", "name", admission.Update), a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
a("g", "v", "r", "", "name", admission.Delete), a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
), ),
}, },
"multiple": { "multiple": {
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Update, adreg.Delete}}, rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Update, adreg.Delete}},
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Update), a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
a("g", "v", "r", "", "name", admission.Delete), a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g", "v", "r", "", "name", admission.Connect), a("g", "v", "r", "", "name", admission.Connect, nil),
), ),
}, },
} }
@@ -254,12 +259,12 @@ func TestResource(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r2", "", "name", admission.Create), a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g", "v", "r", "exec", "name", admission.Create), a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r2", "proxy", "name", admission.Create), a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
"r & subresources": { "r & subresources": {
@@ -269,12 +274,12 @@ func TestResource(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g", "v", "r", "exec", "name", admission.Create), a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("2", "v", "r2", "", "name", admission.Create), a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r2", "proxy", "name", admission.Create), a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
"r & subresources or r2": { "r & subresources or r2": {
@@ -284,12 +289,12 @@ func TestResource(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("g", "v", "r", "exec", "name", admission.Create), a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r2", "", "name", admission.Create), a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("2", "v", "r2", "proxy", "name", admission.Create), a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
"proxy or exec": { "proxy or exec": {
@@ -299,14 +304,14 @@ func TestResource(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
a("g", "v", "r", "exec", "name", admission.Create), a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r2", "proxy", "name", admission.Create), a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r3", "proxy", "name", admission.Create), a("2", "v", "r3", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
a("g", "v", "r", "", "name", admission.Create), a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r2", "", "name", admission.Create), a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
a("2", "v", "r4", "scale", "name", admission.Create), a("2", "v", "r4", "scale", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
} }
@@ -339,16 +344,16 @@ func TestScope(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create), clusterScopedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create), clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create), clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create), clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create), namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create), namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
namespacedAttributes("g", "v", "r", "", "name", admission.Create), namespacedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create), namespacedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
"namespace scope": { "namespace scope": {
@@ -359,16 +364,16 @@ func TestScope(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
namespacedAttributes("g", "v", "r", "", "name", admission.Create), namespacedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create), namespacedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList( noMatch: attrList(
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create), clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create), clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create), namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create), namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create), clusterScopedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create), clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
), ),
}, },
"all scopes": { "all scopes": {
@@ -379,14 +384,14 @@ func TestScope(t *testing.T) {
}, },
}, },
match: attrList( match: attrList(
namespacedAttributes("g", "v", "r", "", "name", admission.Create), namespacedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create), namespacedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create), clusterScopedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create), clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create), clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create), clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create), namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create), namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
), ),
noMatch: attrList(), noMatch: attrList(),
}, },

View File

@@ -101,9 +101,10 @@ func newAttributesRecord(object metav1.Object, oldObject metav1.Object, kind sch
Name: "webhook-test", Name: "webhook-test",
UID: "webhook-test", UID: "webhook-test",
} }
options := &metav1.UpdateOptions{}
return &FakeAttributes{ return &FakeAttributes{
Attributes: admission.NewAttributesRecord(object.(runtime.Object), oldObject.(runtime.Object), kind, namespace, name, gvr, subResource, admission.Update, dryRun, &userInfo), Attributes: admission.NewAttributesRecord(object.(runtime.Object), oldObject.(runtime.Object), kind, namespace, name, gvr, subResource, admission.Update, options, dryRun, &userInfo),
} }
} }

View File

@@ -136,6 +136,7 @@ func TestBanflunderAdmissionPlugin(t *testing.T) {
scenario.admissionInputResource, scenario.admissionInputResource,
"", "",
admission.Create, admission.Create,
&metav1.CreateOptions{},
false, false,
nil), nil),
nil, nil,

View File

@@ -151,9 +151,11 @@ type holder struct {
recordNamespace string recordNamespace string
recordName string recordName string
expectGVK schema.GroupVersionKind expectGVK schema.GroupVersionKind
expectObject bool expectObject bool
expectOldObject bool expectOldObject bool
expectOptionsGVK schema.GroupVersionKind
expectOptions bool
recorded map[string]*v1beta1.AdmissionRequest recorded map[string]*v1beta1.AdmissionRequest
} }
@@ -169,12 +171,14 @@ func (h *holder) reset(t *testing.T) {
h.recordNamespace = "" h.recordNamespace = ""
h.expectObject = false h.expectObject = false
h.expectOldObject = false h.expectOldObject = false
h.expectOptionsGVK = schema.GroupVersionKind{}
h.expectOptions = false
h.recorded = map[string]*v1beta1.AdmissionRequest{ h.recorded = map[string]*v1beta1.AdmissionRequest{
mutation: nil, mutation: nil,
validation: nil, validation: nil,
} }
} }
func (h *holder) expect(gvr schema.GroupVersionResource, gvk schema.GroupVersionKind, operation v1beta1.Operation, name, namespace string, object, oldObject bool) { func (h *holder) expect(gvr schema.GroupVersionResource, gvk, optionsGVK schema.GroupVersionKind, operation v1beta1.Operation, name, namespace string, object, oldObject, options bool) {
// Special-case namespaces, since the object name shows up in request attributes for update/delete requests // Special-case namespaces, since the object name shows up in request attributes for update/delete requests
if len(namespace) == 0 && gvk.Group == "" && gvk.Version == "v1" && gvk.Kind == "Namespace" && operation != v1beta1.Create { if len(namespace) == 0 && gvk.Group == "" && gvk.Version == "v1" && gvk.Kind == "Namespace" && operation != v1beta1.Create {
namespace = name namespace = name
@@ -189,6 +193,8 @@ func (h *holder) expect(gvr schema.GroupVersionResource, gvk schema.GroupVersion
h.recordNamespace = namespace h.recordNamespace = namespace
h.expectObject = object h.expectObject = object
h.expectOldObject = oldObject h.expectOldObject = oldObject
h.expectOptionsGVK = optionsGVK
h.expectOptions = options
h.recorded = map[string]*v1beta1.AdmissionRequest{ h.recorded = map[string]*v1beta1.AdmissionRequest{
mutation: nil, mutation: nil,
validation: nil, validation: nil,
@@ -283,6 +289,14 @@ func (h *holder) verifyRequest(request *v1beta1.AdmissionRequest) error {
return fmt.Errorf("unexpected old object: %#v", request.OldObject.Object) return fmt.Errorf("unexpected old object: %#v", request.OldObject.Object)
} }
if h.expectOptions {
if err := h.verifyOptions(request.Options.Object); err != nil {
return fmt.Errorf("options error: %v", err)
}
} else if request.Options.Object != nil {
return fmt.Errorf("unexpected options: %#v", request.Options.Object)
}
return nil return nil
} }
@@ -296,6 +310,16 @@ func (h *holder) verifyObject(obj runtime.Object) error {
return nil return nil
} }
func (h *holder) verifyOptions(options runtime.Object) error {
if options == nil {
return fmt.Errorf("no options sent")
}
if options.GetObjectKind().GroupVersionKind() != h.expectOptionsGVK {
return fmt.Errorf("expected %#v, got %#v", h.expectOptionsGVK, options.GetObjectKind().GroupVersionKind())
}
return nil
}
// TestWebhookV1beta1 tests communication between API server and webhook process. // TestWebhookV1beta1 tests communication between API server and webhook process.
func TestWebhookV1beta1(t *testing.T) { func TestWebhookV1beta1(t *testing.T) {
// holder communicates expectations to webhooks, and results from webhooks // holder communicates expectations to webhooks, and results from webhooks
@@ -456,7 +480,7 @@ func testResourceCreate(c *testContext) {
if c.resource.Namespaced { if c.resource.Namespaced {
ns = testNamespace ns = testNamespace
} }
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Create, stubObj.GetName(), ns, true, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkCreateOptions, v1beta1.Create, stubObj.GetName(), ns, true, false, true)
_, err = c.client.Resource(c.gvr).Namespace(ns).Create(stubObj, metav1.CreateOptions{}) _, err = c.client.Resource(c.gvr).Namespace(ns).Create(stubObj, metav1.CreateOptions{})
if err != nil { if err != nil {
c.t.Error(err) c.t.Error(err)
@@ -471,7 +495,7 @@ func testResourceUpdate(c *testContext) {
return err return err
} }
obj.SetAnnotations(map[string]string{"update": "true"}) obj.SetAnnotations(map[string]string{"update": "true"})
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkUpdateOptions, v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true, true)
_, err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Update(obj, metav1.UpdateOptions{}) _, err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Update(obj, metav1.UpdateOptions{})
return err return err
}); err != nil { }); err != nil {
@@ -486,7 +510,7 @@ func testResourcePatch(c *testContext) {
c.t.Error(err) c.t.Error(err)
return return
} }
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkUpdateOptions, v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true, true)
_, err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Patch( _, err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Patch(
obj.GetName(), obj.GetName(),
types.MergePatchType, types.MergePatchType,
@@ -506,7 +530,7 @@ func testResourceDelete(c *testContext) {
} }
background := metav1.DeletePropagationBackground background := metav1.DeletePropagationBackground
zero := int64(0) zero := int64(0)
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Delete, obj.GetName(), obj.GetNamespace(), false, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkDeleteOptions, v1beta1.Delete, obj.GetName(), obj.GetNamespace(), false, false, true)
err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Delete(obj.GetName(), &metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background}) err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Delete(obj.GetName(), &metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background})
if err != nil { if err != nil {
c.t.Error(err) c.t.Error(err)
@@ -552,7 +576,7 @@ func testResourceDeletecollection(c *testContext) {
} }
// set expectations // set expectations
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Delete, "", obj.GetNamespace(), false, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkDeleteOptions, v1beta1.Delete, "", obj.GetNamespace(), false, false, true)
// delete // delete
err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).DeleteCollection(&metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background}, metav1.ListOptions{LabelSelector: "webhooktest=true"}) err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).DeleteCollection(&metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background}, metav1.ListOptions{LabelSelector: "webhooktest=true"})
@@ -617,7 +641,7 @@ func testSubresourceUpdate(c *testContext) {
submitObj.SetAnnotations(map[string]string{"subresourceupdate": "true"}) submitObj.SetAnnotations(map[string]string{"subresourceupdate": "true"})
// set expectations // set expectations
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkUpdateOptions, v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true, true)
_, err = c.client.Resource(gvrWithoutSubresources).Namespace(obj.GetNamespace()).Update( _, err = c.client.Resource(gvrWithoutSubresources).Namespace(obj.GetNamespace()).Update(
submitObj, submitObj,
@@ -644,7 +668,7 @@ func testSubresourcePatch(c *testContext) {
subresources := strings.Split(c.gvr.Resource, "/")[1:] subresources := strings.Split(c.gvr.Resource, "/")[1:]
// set expectations // set expectations
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkUpdateOptions, v1beta1.Update, obj.GetName(), obj.GetNamespace(), true, true, true)
_, err = c.client.Resource(gvrWithoutSubresources).Namespace(obj.GetNamespace()).Patch( _, err = c.client.Resource(gvrWithoutSubresources).Namespace(obj.GetNamespace()).Patch(
obj.GetName(), obj.GetName(),
@@ -680,7 +704,7 @@ func testNamespaceDelete(c *testContext) {
background := metav1.DeletePropagationBackground background := metav1.DeletePropagationBackground
zero := int64(0) zero := int64(0)
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Delete, obj.GetName(), obj.GetNamespace(), false, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkDeleteOptions, v1beta1.Delete, obj.GetName(), obj.GetNamespace(), false, false, true)
err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Delete(obj.GetName(), &metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background}) err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Delete(obj.GetName(), &metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background})
if err != nil { if err != nil {
c.t.Error(err) c.t.Error(err)
@@ -706,7 +730,7 @@ func testNamespaceDelete(c *testContext) {
} }
// then run the final delete and make sure admission is called again // then run the final delete and make sure admission is called again
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Delete, obj.GetName(), obj.GetNamespace(), false, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkDeleteOptions, v1beta1.Delete, obj.GetName(), obj.GetNamespace(), false, false, true)
err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Delete(obj.GetName(), &metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background}) err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).Delete(obj.GetName(), &metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background})
if err != nil { if err != nil {
c.t.Error(err) c.t.Error(err)
@@ -736,7 +760,7 @@ func testDeploymentRollback(c *testContext) {
gvrWithoutSubresources.Resource = strings.Split(gvrWithoutSubresources.Resource, "/")[0] gvrWithoutSubresources.Resource = strings.Split(gvrWithoutSubresources.Resource, "/")[0]
subresources := strings.Split(c.gvr.Resource, "/")[1:] subresources := strings.Split(c.gvr.Resource, "/")[1:]
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Create, obj.GetName(), obj.GetNamespace(), true, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkCreateOptions, v1beta1.Create, obj.GetName(), obj.GetNamespace(), true, false, true)
var rollbackObj runtime.Object var rollbackObj runtime.Object
switch c.gvr { switch c.gvr {
@@ -785,7 +809,7 @@ func testPodConnectSubresource(c *testContext) {
for _, httpMethod := range []string{"GET", "POST"} { for _, httpMethod := range []string{"GET", "POST"} {
c.t.Logf("verifying %v", httpMethod) c.t.Logf("verifying %v", httpMethod)
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Connect, pod.GetName(), pod.GetNamespace(), true, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), schema.GroupVersionKind{}, v1beta1.Connect, pod.GetName(), pod.GetNamespace(), true, false, false)
var err error var err error
switch c.gvr { switch c.gvr {
case gvr("", "v1", "pods/exec"): case gvr("", "v1", "pods/exec"):
@@ -827,7 +851,7 @@ func testPodBindingEviction(c *testContext) {
} }
}() }()
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Create, pod.GetName(), pod.GetNamespace(), true, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), gvkCreateOptions, v1beta1.Create, pod.GetName(), pod.GetNamespace(), true, false, true)
switch c.gvr { switch c.gvr {
case gvr("", "v1", "bindings"): case gvr("", "v1", "bindings"):
@@ -895,7 +919,7 @@ func testSubresourceProxy(c *testContext) {
} }
// set expectations // set expectations
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Connect, obj.GetName(), obj.GetNamespace(), true, false) c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), schema.GroupVersionKind{}, v1beta1.Connect, obj.GetName(), obj.GetNamespace(), true, false, false)
// run the request. we don't actually care if the request is successful, just that admission gets called as expected // run the request. we don't actually care if the request is successful, just that admission gets called as expected
err = request.Resource(gvrWithoutSubresources.Resource).Name(obj.GetName()).SubResource(subresources...).Do().Error() err = request.Resource(gvrWithoutSubresources.Resource).Name(obj.GetName()).SubResource(subresources...).Do().Error()
if err != nil { if err != nil {
@@ -918,6 +942,7 @@ func newWebhookHandler(t *testing.T, holder *holder, phase string) http.Handler
t.Error(err) t.Error(err)
return return
} }
if contentType := r.Header.Get("Content-Type"); contentType != "application/json" { if contentType := r.Header.Get("Content-Type"); contentType != "application/json" {
t.Errorf("contentType=%s, expect application/json", contentType) t.Errorf("contentType=%s, expect application/json", contentType)
return return
@@ -955,6 +980,16 @@ func newWebhookHandler(t *testing.T, holder *holder, phase string) http.Handler
review.Request.OldObject.Object = u review.Request.OldObject.Object = u
} }
if len(review.Request.Options.Raw) > 0 {
u := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := json.Unmarshal(review.Request.Options.Raw, u); err != nil {
t.Errorf("Fail to deserialize options object: %s for admission request %#+v with error: %v", string(review.Request.Options.Raw), review.Request, err)
http.Error(w, err.Error(), 400)
return
}
review.Request.Options.Object = u
}
if review.Request.UserInfo.Username == testClientUsername { if review.Request.UserInfo.Username == testClientUsername {
// only record requests originating from this integration test's client // only record requests originating from this integration test's client
holder.record(phase, review.Request) holder.record(phase, review.Request)
@@ -1043,6 +1078,12 @@ func gvk(group, version, kind string) schema.GroupVersionKind {
return schema.GroupVersionKind{Group: group, Version: version, Kind: kind} return schema.GroupVersionKind{Group: group, Version: version, Kind: kind}
} }
var (
gvkCreateOptions = metav1.SchemeGroupVersion.WithKind("CreateOptions")
gvkUpdateOptions = metav1.SchemeGroupVersion.WithKind("UpdateOptions")
gvkDeleteOptions = metav1.SchemeGroupVersion.WithKind("DeleteOptions")
)
func shouldTestResource(gvr schema.GroupVersionResource, resource metav1.APIResource) bool { func shouldTestResource(gvr schema.GroupVersionResource, resource metav1.APIResource) bool {
if !sets.NewString(resource.Verbs...).HasAny("create", "update", "patch", "connect", "delete", "deletecollection") { if !sets.NewString(resource.Verbs...).HasAny("create", "update", "patch", "connect", "delete", "deletecollection") {
return false return false