Merge pull request #77563 from jpbetz/admission-webhook-options
Pass {Operation}Options to Webhooks
This commit is contained in:
@@ -63,7 +63,8 @@ type AdmissionRequest struct {
|
||||
// Namespace is the namespace associated with the request (if any).
|
||||
// +optional
|
||||
Namespace string
|
||||
// Operation is the operation being performed
|
||||
// Operation is the operation being performed. This may be different than the operation
|
||||
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
|
||||
Operation Operation
|
||||
// UserInfo is information about the requesting user
|
||||
UserInfo authentication.UserInfo
|
||||
@@ -78,6 +79,13 @@ type AdmissionRequest struct {
|
||||
// Defaults to false.
|
||||
// +optional
|
||||
DryRun *bool
|
||||
// Options is the operation option structure of the operation being performed.
|
||||
// e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
|
||||
// different than the options the caller provided. e.g. for a patch request the performed
|
||||
// Operation might be a CREATE, in which case the Options will a
|
||||
// `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
|
||||
// +optional
|
||||
Options runtime.Object
|
||||
}
|
||||
|
||||
// AdmissionResponse describes an admission response.
|
||||
|
@@ -90,6 +90,9 @@ func autoConvert_v1beta1_AdmissionRequest_To_admission_AdmissionRequest(in *v1be
|
||||
return err
|
||||
}
|
||||
out.DryRun = (*bool)(unsafe.Pointer(in.DryRun))
|
||||
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.Options, &out.Options, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -117,6 +120,9 @@ func autoConvert_admission_AdmissionRequest_To_v1beta1_AdmissionRequest(in *admi
|
||||
return err
|
||||
}
|
||||
out.DryRun = (*bool)(unsafe.Pointer(in.DryRun))
|
||||
if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.Options, &out.Options, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
3
pkg/apis/admission/zz_generated.deepcopy.go
generated
3
pkg/apis/admission/zz_generated.deepcopy.go
generated
@@ -42,6 +42,9 @@ func (in *AdmissionRequest) DeepCopyInto(out *AdmissionRequest) {
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Options != nil {
|
||||
out.Options = in.Options.DeepCopyObject()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//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",
|
||||
],
|
||||
)
|
||||
|
@@ -19,13 +19,14 @@ package admit
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
func TestAdmissionNonNilAttribute(t *testing.T) {
|
||||
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 {
|
||||
t.Errorf("Unexpected error returned from admission handler")
|
||||
}
|
||||
|
@@ -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 {
|
||||
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"`
|
||||
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 {
|
||||
t.Fatal("missing expected error")
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func TestOtherResources(t *testing.T) {
|
||||
for _, tc := range tests {
|
||||
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 err == nil {
|
||||
|
@@ -19,7 +19,7 @@ package antiaffinity
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
@@ -199,7 +199,7 @@ func TestInterPodAffinityAdmission(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
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 {
|
||||
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 {
|
||||
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 err == nil {
|
||||
|
@@ -263,7 +263,7 @@ func TestForgivenessAdmission(t *testing.T) {
|
||||
}
|
||||
|
||||
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 {
|
||||
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//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",
|
||||
],
|
||||
)
|
||||
|
@@ -19,13 +19,14 @@ package deny
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
func TestAdmission(t *testing.T) {
|
||||
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 {
|
||||
t.Error("Expected error returned from admission handler")
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ go_test(
|
||||
"//pkg/apis/core: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/apis/meta/v1: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/apiserver/pkg/admission:go_default_library",
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
@@ -46,6 +47,7 @@ func attributesForRequest(rq request) admission.Attributes {
|
||||
api.Resource("resource").WithVersion("version"),
|
||||
"",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
rq.dryRun,
|
||||
&user.DefaultInfo{Name: rq.username})
|
||||
}
|
||||
|
@@ -120,7 +120,7 @@ func testAdmission(t *testing.T, pod *corev1.Pod, handler *DenyExec, shouldAccep
|
||||
|
||||
// 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 {
|
||||
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
|
||||
{
|
||||
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 {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
|
@@ -354,7 +354,7 @@ func TestAdmit(t *testing.T) {
|
||||
},
|
||||
}
|
||||
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 {
|
||||
t.Errorf("[%d: %s] unexpected error %v for pod %+v", i, test.description, err, test.requestedPod)
|
||||
}
|
||||
|
@@ -302,11 +302,13 @@ func TestGCAdmission(t *testing.T) {
|
||||
}
|
||||
|
||||
operation := admission.Create
|
||||
var options runtime.Object = &metav1.CreateOptions{}
|
||||
if tc.oldObj != nil {
|
||||
operation = admission.Update
|
||||
options = &metav1.UpdateOptions{}
|
||||
}
|
||||
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)
|
||||
if !tc.checkError(err) {
|
||||
@@ -605,11 +607,13 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
operation := admission.Create
|
||||
var options runtime.Object = &metav1.CreateOptions{}
|
||||
if tc.oldObj != nil {
|
||||
operation = admission.Update
|
||||
options = &metav1.UpdateOptions{}
|
||||
}
|
||||
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)
|
||||
if !tc.checkError(err) {
|
||||
|
@@ -42,6 +42,7 @@ go_test(
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/imagepolicy/install: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/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",
|
||||
|
@@ -29,9 +29,10 @@ import (
|
||||
"time"
|
||||
|
||||
"k8s.io/api/imagepolicy/v1alpha1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"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"
|
||||
|
||||
"fmt"
|
||||
@@ -482,7 +483,7 @@ func TestTLSConfig(t *testing.T) {
|
||||
return
|
||||
}
|
||||
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.
|
||||
service.Allow()
|
||||
@@ -571,7 +572,7 @@ func TestWebhookCache(t *testing.T) {
|
||||
{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
|
||||
|
||||
@@ -583,7 +584,7 @@ func TestWebhookCache(t *testing.T) {
|
||||
{statusCode: 200, expectedErr: false, expectedAuthorized: true, expectedCached: false},
|
||||
{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)
|
||||
}
|
||||
@@ -757,7 +758,7 @@ func TestContainerCombinations(t *testing.T) {
|
||||
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)
|
||||
if tt.wantAllowed {
|
||||
@@ -851,7 +852,7 @@ func TestDefaultAllow(t *testing.T) {
|
||||
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)
|
||||
attr = &fakeAttributes{attr, annotations}
|
||||
|
||||
@@ -961,7 +962,7 @@ func TestAnnotationFiltering(t *testing.T) {
|
||||
pod := goodPod("test")
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -1051,7 +1052,7 @@ func TestReturnedAnnotationAdd(t *testing.T) {
|
||||
|
||||
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)
|
||||
attr = &fakeAttributes{attr, annotations}
|
||||
|
||||
|
@@ -35,7 +35,7 @@ import (
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
core "k8s.io/client-go/testing"
|
||||
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 {
|
||||
@@ -705,20 +705,20 @@ func TestLimitRangerIgnoresSubresource(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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)
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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{})
|
||||
now := metav1.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 {
|
||||
t.Errorf("LimitRange should ignore a pod marked for termination")
|
||||
}
|
||||
|
@@ -99,7 +99,7 @@ func TestAdmission(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func TestAdmissionDryRun(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func TestIgnoreAdmission(t *testing.T) {
|
||||
chainHandler := admission.NewChainHandler(handler)
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -182,7 +182,7 @@ func TestAdmissionWithLatentCache(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
|
@@ -88,7 +88,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
actions := ""
|
||||
for _, action := range mockClient.Actions() {
|
||||
|
@@ -374,61 +374,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "allow creating a mirror pod bound to self",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid update of mirror pod bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow delete of mirror pod bound to self",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid create of mirror pod status bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow update of mirror pod status bound to self",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of mirror pod status bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow create of eviction for mirror pod bound to self",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for mirror pod bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for mirror pod bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow create of unnamed eviction for mirror pod bound to self",
|
||||
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: "",
|
||||
},
|
||||
|
||||
@@ -436,61 +436,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid creating a mirror pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of mirror pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of mirror pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of mirror pod status bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of mirror pod status bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of mirror pod status bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of eviction for mirror pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for mirror pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for mirror pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of unnamed eviction for mirror pod to another",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -498,61 +498,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid creating a mirror pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of mirror pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of mirror pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of mirror pod status unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of mirror pod status unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of mirror pod status unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of eviction for mirror pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for mirror pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for mirror pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of unnamed eviction for mirror pod unbound",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -560,55 +560,55 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid creating a normal pod bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of normal pod bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow delete of normal pod bound to self",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid create of normal pod status bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow update of normal pod status bound to self",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of normal pod status bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for normal pod bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for normal pod bound to self",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow create of unnamed eviction for normal pod bound to self",
|
||||
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: "",
|
||||
},
|
||||
|
||||
@@ -616,61 +616,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid creating a normal pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of normal pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of normal pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of normal pod status bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of normal pod status bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of normal pod status bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of eviction for normal pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for normal pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for normal pod bound to another",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of unnamed eviction for normal pod bound to another",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -678,61 +678,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid creating a normal pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of normal pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of normal pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of normal pod status unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of normal pod status unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of normal pod status unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of eviction for normal pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for normal pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for normal pod unbound",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of unnamed eviction for normal unbound",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -740,31 +740,31 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid delete of unknown pod",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of eviction for unknown pod",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for unknown pod",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for unknown pod",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of unnamed eviction for unknown pod",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -772,26 +772,26 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "allow create of eviction for unnamed pod",
|
||||
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
|
||||
err: "",
|
||||
},
|
||||
{
|
||||
name: "forbid update of eviction for unnamed pod",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of eviction for unnamed pod",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of unnamed eviction for unnamed pod",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -799,25 +799,25 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid create of pod referencing service account",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of pod referencing secret",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of pod referencing configmap",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of pod referencing persistentvolumeclaim",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -825,157 +825,157 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "allow create of my node",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow create of my node pulling name from object",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow create of my node with taints",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow create of my node with labels",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid create of my node with forbidden labels",
|
||||
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`,
|
||||
},
|
||||
{
|
||||
name: "allow update of my node",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow delete of my node",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node status",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid create of my node with non-nil configSource",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: nil configSource to new non-nil configSource",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: non-nil configSource to new non-nil configSource",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: non-nil configSource unchanged",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: non-nil configSource to nil configSource",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: no change to taints",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: add allowed labels",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: remove allowed labels",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: modify allowed labels",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: no change to labels",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: add allowed labels while forbidden labels exist unmodified",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of my node: remove allowed labels while forbidden labels exist unmodified",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: add taints",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: remove taints",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: change taints",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: add labels",
|
||||
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`,
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: remove labels",
|
||||
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`,
|
||||
},
|
||||
{
|
||||
name: "forbid update of my node: change labels",
|
||||
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`,
|
||||
},
|
||||
|
||||
@@ -983,31 +983,31 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "forbid create of other node",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of other node pulling name from object",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of other node",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid delete of other node",
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid update of other node status",
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -1016,54 +1016,54 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
name: "forbid create of unbound token",
|
||||
podsGetter: noExistingPods,
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of token bound to nonexistant pod",
|
||||
podsGetter: noExistingPods,
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of token bound to pod without uid",
|
||||
podsGetter: existingPods,
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "forbid create of token bound to pod scheduled on another node",
|
||||
podsGetter: existingPods,
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "allow create of token bound to pod scheduled this node",
|
||||
podsGetter: existingPods,
|
||||
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
|
||||
{
|
||||
name: "allow create of unrelated object",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow update of unrelated object",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow delete of unrelated object",
|
||||
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: "",
|
||||
},
|
||||
|
||||
@@ -1071,140 +1071,140 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
{
|
||||
name: "allow unrelated user creating a normal pod unbound",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow unrelated user update of normal pod unbound",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow unrelated user delete of normal pod unbound",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow unrelated user create of normal pod status unbound",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow unrelated user update of normal pod status unbound",
|
||||
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: "",
|
||||
},
|
||||
{
|
||||
name: "allow unrelated user delete of normal pod status unbound",
|
||||
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: "",
|
||||
},
|
||||
// Node leases
|
||||
{
|
||||
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,
|
||||
err: "forbidden: disabled by feature gate NodeLease",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "",
|
||||
},
|
||||
// CSINode
|
||||
{
|
||||
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,
|
||||
err: fmt.Sprintf("forbidden: disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo),
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "forbidden: ",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "",
|
||||
},
|
||||
{
|
||||
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,
|
||||
err: "",
|
||||
},
|
||||
|
@@ -22,6 +22,7 @@ go_test(
|
||||
"//pkg/apis/core: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/runtime: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/component-base/featuregate:go_default_library",
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/component-base/featuregate"
|
||||
@@ -62,6 +63,7 @@ func Test_nodeTaints(t *testing.T) {
|
||||
oldNode api.Node
|
||||
features featuregate.FeatureGate
|
||||
operation admission.Operation
|
||||
options runtime.Object
|
||||
expectedTaints []api.Taint
|
||||
}{
|
||||
{
|
||||
@@ -69,6 +71,7 @@ func Test_nodeTaints(t *testing.T) {
|
||||
node: myNodeObj,
|
||||
features: enableTaintNodesByCondition,
|
||||
operation: admission.Create,
|
||||
options: &metav1.CreateOptions{},
|
||||
expectedTaints: []api.Taint{notReadyTaint},
|
||||
},
|
||||
{
|
||||
@@ -76,6 +79,7 @@ func Test_nodeTaints(t *testing.T) {
|
||||
node: myNodeObj,
|
||||
features: disableTaintNodesByCondition,
|
||||
operation: admission.Create,
|
||||
options: &metav1.CreateOptions{},
|
||||
expectedTaints: nil,
|
||||
},
|
||||
{
|
||||
@@ -83,6 +87,7 @@ func Test_nodeTaints(t *testing.T) {
|
||||
node: myTaintedNodeObj,
|
||||
features: enableTaintNodesByCondition,
|
||||
operation: admission.Create,
|
||||
options: &metav1.CreateOptions{},
|
||||
expectedTaints: []api.Taint{notReadyTaint},
|
||||
},
|
||||
{
|
||||
@@ -90,12 +95,13 @@ func Test_nodeTaints(t *testing.T) {
|
||||
node: myUnreadyNodeObj,
|
||||
features: enableTaintNodesByCondition,
|
||||
operation: admission.Create,
|
||||
options: &metav1.CreateOptions{},
|
||||
expectedTaints: []api.Taint{notReadyTaint},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
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()
|
||||
if tt.features != nil {
|
||||
c.features = tt.features
|
||||
|
@@ -161,7 +161,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
handler.clusterNodeSelectors[namespace.Name] = test.whitelist
|
||||
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 {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} 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)) {
|
||||
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 {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
|
@@ -819,6 +819,7 @@ func admitPod(pod *api.Pod, pip *settingsv1alpha1.PodPreset) error {
|
||||
api.Resource("pods").WithVersion("version"),
|
||||
"",
|
||||
kadmission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
false,
|
||||
&user.DefaultInfo{},
|
||||
)
|
||||
|
@@ -266,7 +266,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
pod := test.pod
|
||||
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 {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} 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.
|
||||
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 {
|
||||
t.Errorf("expected no error, got: %v", err)
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ import (
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"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/features"
|
||||
)
|
||||
@@ -155,6 +155,7 @@ func TestPriorityClassAdmission(t *testing.T) {
|
||||
scheduling.Resource("priorityclasses").WithVersion("version"),
|
||||
"",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
false,
|
||||
test.userInfo,
|
||||
)
|
||||
@@ -200,7 +201,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "add a default class",
|
||||
classesBefore: []*scheduling.PriorityClass{nondefaultClass1},
|
||||
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,
|
||||
expectedDefaultNameBefore: "",
|
||||
expectedDefaultAfter: defaultClass1.Value,
|
||||
@@ -210,7 +211,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "multiple default classes resolves to the minimum value among them",
|
||||
classesBefore: []*scheduling.PriorityClass{defaultClass1, 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,
|
||||
expectedDefaultNameBefore: defaultClass1.Name,
|
||||
expectedDefaultAfter: defaultClass2.Value,
|
||||
@@ -220,7 +221,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "delete default priority class",
|
||||
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
||||
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,
|
||||
expectedDefaultNameBefore: defaultClass1.Name,
|
||||
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||
@@ -230,7 +231,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "update default class and remove its global default",
|
||||
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
||||
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,
|
||||
expectedDefaultNameBefore: defaultClass1.Name,
|
||||
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||
@@ -600,6 +601,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
api.Resource("pods").WithVersion("version"),
|
||||
"",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
|
@@ -153,7 +153,7 @@ func TestAdmissionIgnoresDelete(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
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 {
|
||||
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)
|
||||
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 {
|
||||
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 {
|
||||
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)
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -318,13 +318,13 @@ func TestAdmitDryRun(t *testing.T) {
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
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 {
|
||||
t.Errorf("Expected error but got none")
|
||||
}
|
||||
@@ -384,7 +384,7 @@ func TestAdmitHandlesOldObjects(t *testing.T) {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -641,7 +641,7 @@ func TestAdmitHandlesCreatingUpdates(t *testing.T) {
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -724,7 +724,7 @@ func TestAdmitExceedQuotaLimit(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
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 {
|
||||
t.Errorf("Expected an error exceeding quota")
|
||||
}
|
||||
@@ -770,7 +770,7 @@ func TestAdmitEnforceQuotaConstraints(t *testing.T) {
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
// verify all values are specified as required on the quota
|
||||
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 {
|
||||
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", "")))
|
||||
// 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{}})
|
||||
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 {
|
||||
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("", "")))
|
||||
activeDeadlineSeconds := int64(30)
|
||||
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 {
|
||||
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
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1084,7 +1084,7 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1193,7 +1193,7 @@ func TestAdmissionSetsMissingNamespace(t *testing.T) {
|
||||
// unset the 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 {
|
||||
t.Errorf("Got unexpected error: %v", err)
|
||||
}
|
||||
@@ -1236,14 +1236,14 @@ func TestAdmitRejectsNegativeUsage(t *testing.T) {
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
// verify quota rejects negative pvc storage requests
|
||||
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 {
|
||||
t.Errorf("Expected an error because the pvc has negative storage usage")
|
||||
}
|
||||
|
||||
// verify quota accepts non-negative pvc storage requests
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1284,7 +1284,7 @@ func TestAdmitWhenUnrelatedResourceExceedsQuota(t *testing.T) {
|
||||
|
||||
// create a pod that should pass existing quota
|
||||
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 {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1318,7 +1318,7 @@ func TestAdmitLimitedResourceNoQuota(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
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 {
|
||||
t.Errorf("Expected an error for consuming a limited resource without quota.")
|
||||
}
|
||||
@@ -1352,7 +1352,7 @@ func TestAdmitLimitedResourceNoQuotaIgnoresNonMatchingResources(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
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 {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1400,7 +1400,7 @@ func TestAdmitLimitedResourceWithQuota(t *testing.T) {
|
||||
}
|
||||
indexer.Add(resourceQuota)
|
||||
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 {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -1460,7 +1460,7 @@ func TestAdmitLimitedResourceWithMultipleQuota(t *testing.T) {
|
||||
indexer.Add(resourceQuota1)
|
||||
indexer.Add(resourceQuota2)
|
||||
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 {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -1508,7 +1508,7 @@ func TestAdmitLimitedResourceWithQuotaThatDoesNotCover(t *testing.T) {
|
||||
}
|
||||
indexer.Add(resourceQuota)
|
||||
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 {
|
||||
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 {
|
||||
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 err != nil {
|
||||
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},
|
||||
}
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -2267,7 +2267,7 @@ func TestAdmitRejectIncreaseUsageWithoutCoveringQuota(t *testing.T) {
|
||||
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 {
|
||||
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 {
|
||||
t.Errorf("Expected no error for decreasing a limited resource without quota, got %v", err)
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
policy "k8s.io/api/policy/v1beta1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -473,7 +473,7 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
func TestFailClosedOnInvalidPod(t *testing.T) {
|
||||
plugin := NewTestAdmission(nil, nil)
|
||||
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)
|
||||
if err == nil {
|
||||
@@ -1776,7 +1776,7 @@ func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*
|
||||
originalPod := pod.DeepCopy()
|
||||
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)
|
||||
attrs = &fakeAttributes{attrs, annotations}
|
||||
err := plugin.Admit(attrs, nil)
|
||||
@@ -2240,7 +2240,7 @@ func TestPolicyAuthorizationErrors(t *testing.T) {
|
||||
pod.Spec.SecurityContext.HostPID = true
|
||||
|
||||
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, "")
|
||||
assert.Nil(t, allowedPod)
|
||||
@@ -2333,7 +2333,7 @@ func TestPreferValidatedPSP(t *testing.T) {
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation
|
||||
|
||||
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)
|
||||
assert.NoError(t, err)
|
||||
|
@@ -82,7 +82,7 @@ func TestAdmission(t *testing.T) {
|
||||
p.Spec.SecurityContext = tc.podSc
|
||||
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 {
|
||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||
} else if err == nil && tc.expectError {
|
||||
@@ -96,7 +96,7 @@ func TestAdmission(t *testing.T) {
|
||||
p.Spec.InitContainers = p.Spec.Containers
|
||||
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 {
|
||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||
} else if err == nil && tc.expectError {
|
||||
@@ -140,7 +140,7 @@ func TestPodSecurityContextAdmission(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
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 {
|
||||
t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext)
|
||||
|
@@ -64,7 +64,7 @@ func TestIgnoresNonCreate(t *testing.T) {
|
||||
|
||||
func TestIgnoresNonPodResource(t *testing.T) {
|
||||
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)
|
||||
if err != nil {
|
||||
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) {
|
||||
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)
|
||||
if err != nil {
|
||||
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) {
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
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",
|
||||
},
|
||||
}
|
||||
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)
|
||||
if err == nil {
|
||||
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)
|
||||
if err == nil {
|
||||
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)
|
||||
if err == nil {
|
||||
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{}
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -217,7 +217,7 @@ func TestAssignsDefaultServiceAccountAndRejectsMissingAPIToken(t *testing.T) {
|
||||
})
|
||||
|
||||
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)
|
||||
if err == nil || !errors.IsServerTimeout(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
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -264,7 +264,7 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
|
||||
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)
|
||||
if err == nil {
|
||||
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)
|
||||
if err != nil {
|
||||
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 {
|
||||
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)
|
||||
if err != nil {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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") {
|
||||
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") {
|
||||
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)
|
||||
if err == nil {
|
||||
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"}},
|
||||
},
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -735,7 +735,7 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) {
|
||||
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)
|
||||
if err == nil {
|
||||
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"}},
|
||||
},
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -802,7 +802,7 @@ func TestAddImagePullSecrets(t *testing.T) {
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(sa)
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
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 {
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
|
@@ -23,7 +23,7 @@ import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -756,7 +756,7 @@ func Test_PVLAdmission(t *testing.T) {
|
||||
setPVLabeler(testcase.handler, testcase.pvlabeler)
|
||||
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) {
|
||||
t.Logf("expected error: %q", testcase.err)
|
||||
t.Logf("actual error: %q", err)
|
||||
|
@@ -254,7 +254,8 @@ func TestPVCResizeAdmission(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
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)
|
||||
if !tc.checkError(err) {
|
||||
|
@@ -208,6 +208,7 @@ func TestAdmission(t *testing.T) {
|
||||
api.Resource("persistentvolumeclaims").WithVersion("version"),
|
||||
"", // subresource
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
false, // dryRun
|
||||
nil, // userInfo
|
||||
)
|
||||
|
@@ -131,6 +131,7 @@ func TestAdmit(t *testing.T) {
|
||||
test.resource,
|
||||
"", // subresource
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
false, // dryRun
|
||||
nil, // userInfo
|
||||
)
|
||||
|
160
staging/src/k8s.io/api/admission/v1beta1/generated.pb.go
generated
160
staging/src/k8s.io/api/admission/v1beta1/generated.pb.go
generated
@@ -158,6 +158,14 @@ func (m *AdmissionRequest) MarshalTo(dAtA []byte) (int, error) {
|
||||
}
|
||||
i++
|
||||
}
|
||||
dAtA[i] = 0x62
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Options.Size()))
|
||||
n6, err := m.Options.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n6
|
||||
return i, nil
|
||||
}
|
||||
|
||||
@@ -192,11 +200,11 @@ func (m *AdmissionResponse) MarshalTo(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0x1a
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Result.Size()))
|
||||
n6, err := m.Result.MarshalTo(dAtA[i:])
|
||||
n7, err := m.Result.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n6
|
||||
i += n7
|
||||
}
|
||||
if m.Patch != nil {
|
||||
dAtA[i] = 0x22
|
||||
@@ -254,21 +262,21 @@ func (m *AdmissionReview) MarshalTo(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Request.Size()))
|
||||
n7, err := m.Request.MarshalTo(dAtA[i:])
|
||||
n8, err := m.Request.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n7
|
||||
i += n8
|
||||
}
|
||||
if m.Response != nil {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Response.Size()))
|
||||
n8, err := m.Response.MarshalTo(dAtA[i:])
|
||||
n9, err := m.Response.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n8
|
||||
i += n9
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
@@ -308,6 +316,8 @@ func (m *AdmissionRequest) Size() (n int) {
|
||||
if m.DryRun != nil {
|
||||
n += 2
|
||||
}
|
||||
l = m.Options.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
@@ -383,6 +393,7 @@ func (this *AdmissionRequest) String() string {
|
||||
`Object:` + strings.Replace(strings.Replace(this.Object.String(), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`,
|
||||
`OldObject:` + strings.Replace(strings.Replace(this.OldObject.String(), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`,
|
||||
`DryRun:` + valueToStringGenerated(this.DryRun) + `,`,
|
||||
`Options:` + strings.Replace(strings.Replace(this.Options.String(), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
@@ -776,6 +787,36 @@ func (m *AdmissionRequest) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
b := bool(v != 0)
|
||||
m.DryRun = &b
|
||||
case 12:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
@@ -1334,57 +1375,58 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 821 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcf, 0x6f, 0xe3, 0x44,
|
||||
0x14, 0x8e, 0x37, 0x69, 0x12, 0x4f, 0x2a, 0x36, 0x3b, 0x80, 0x64, 0x45, 0xc8, 0x09, 0x3d, 0xa0,
|
||||
0x20, 0x6d, 0xc7, 0xb4, 0x82, 0x55, 0xb5, 0xe2, 0x12, 0xd3, 0x08, 0x55, 0x48, 0xdb, 0x6a, 0x76,
|
||||
0x83, 0x80, 0x03, 0xd2, 0xc4, 0x9e, 0x4d, 0x4c, 0xe2, 0x19, 0xe3, 0x99, 0x49, 0xc9, 0x0d, 0x71,
|
||||
0xe5, 0x82, 0xc4, 0x9f, 0xc4, 0xa5, 0xc7, 0x3d, 0xee, 0x29, 0xa2, 0xe1, 0xbf, 0xe8, 0x09, 0x79,
|
||||
0x3c, 0x8e, 0x43, 0xba, 0x85, 0x5d, 0xb4, 0x27, 0xfb, 0xfd, 0xf8, 0xbe, 0x37, 0xf3, 0xbd, 0x37,
|
||||
0x0f, 0x0c, 0x67, 0x27, 0x02, 0x45, 0xdc, 0x9b, 0xa9, 0x31, 0x4d, 0x19, 0x95, 0x54, 0x78, 0x0b,
|
||||
0xca, 0x42, 0x9e, 0x7a, 0x26, 0x40, 0x92, 0xc8, 0x23, 0x61, 0x1c, 0x09, 0x11, 0x71, 0xe6, 0x2d,
|
||||
0x8e, 0xc6, 0x54, 0x92, 0x23, 0x6f, 0x42, 0x19, 0x4d, 0x89, 0xa4, 0x21, 0x4a, 0x52, 0x2e, 0x39,
|
||||
0xfc, 0x20, 0xcf, 0x46, 0x24, 0x89, 0xd0, 0x26, 0x1b, 0x99, 0xec, 0xce, 0xe1, 0x24, 0x92, 0x53,
|
||||
0x35, 0x46, 0x01, 0x8f, 0xbd, 0x09, 0x9f, 0x70, 0x4f, 0x83, 0xc6, 0xea, 0xb9, 0xb6, 0xb4, 0xa1,
|
||||
0xff, 0x72, 0xb2, 0xce, 0xc3, 0xed, 0xd2, 0x4a, 0x4e, 0x29, 0x93, 0x51, 0x40, 0x64, 0x5e, 0x7f,
|
||||
0xb7, 0x74, 0xe7, 0xd3, 0x32, 0x3b, 0x26, 0xc1, 0x34, 0x62, 0x34, 0x5d, 0x7a, 0xc9, 0x6c, 0x92,
|
||||
0x39, 0x84, 0x17, 0x53, 0x49, 0x5e, 0x85, 0xf2, 0xee, 0x42, 0xa5, 0x8a, 0xc9, 0x28, 0xa6, 0xb7,
|
||||
0x00, 0x8f, 0xfe, 0x0b, 0x20, 0x82, 0x29, 0x8d, 0xc9, 0x2e, 0xee, 0xe0, 0xf7, 0x3a, 0x68, 0x0f,
|
||||
0x0a, 0x45, 0x30, 0xfd, 0x51, 0x51, 0x21, 0xa1, 0x0f, 0xaa, 0x2a, 0x0a, 0x1d, 0xab, 0x67, 0xf5,
|
||||
0x6d, 0xff, 0x93, 0xab, 0x55, 0xb7, 0xb2, 0x5e, 0x75, 0xab, 0xa3, 0xb3, 0xd3, 0x9b, 0x55, 0xf7,
|
||||
0xc3, 0xbb, 0x0a, 0xc9, 0x65, 0x42, 0x05, 0x1a, 0x9d, 0x9d, 0xe2, 0x0c, 0x0c, 0xbf, 0x01, 0xb5,
|
||||
0x59, 0xc4, 0x42, 0xe7, 0x5e, 0xcf, 0xea, 0xb7, 0x8e, 0x1f, 0xa1, 0xb2, 0x03, 0x1b, 0x18, 0x4a,
|
||||
0x66, 0x93, 0xcc, 0x21, 0x50, 0x26, 0x03, 0x5a, 0x1c, 0xa1, 0x2f, 0x53, 0xae, 0x92, 0xaf, 0x69,
|
||||
0x9a, 0x1d, 0xe6, 0xab, 0x88, 0x85, 0xfe, 0xbe, 0x29, 0x5e, 0xcb, 0x2c, 0xac, 0x19, 0xe1, 0x14,
|
||||
0x34, 0x53, 0x2a, 0xb8, 0x4a, 0x03, 0xea, 0x54, 0x35, 0xfb, 0xe3, 0x37, 0x67, 0xc7, 0x86, 0xc1,
|
||||
0x6f, 0x9b, 0x0a, 0xcd, 0xc2, 0x83, 0x37, 0xec, 0xf0, 0x33, 0xd0, 0x12, 0x6a, 0x5c, 0x04, 0x9c,
|
||||
0x9a, 0xd6, 0xe3, 0x5d, 0x03, 0x68, 0x3d, 0x2d, 0x43, 0x78, 0x3b, 0x0f, 0xf6, 0x40, 0x8d, 0x91,
|
||||
0x98, 0x3a, 0x7b, 0x3a, 0x7f, 0x73, 0x85, 0x27, 0x24, 0xa6, 0x58, 0x47, 0xa0, 0x07, 0xec, 0xec,
|
||||
0x2b, 0x12, 0x12, 0x50, 0xa7, 0xae, 0xd3, 0x1e, 0x98, 0x34, 0xfb, 0x49, 0x11, 0xc0, 0x65, 0x0e,
|
||||
0xfc, 0x1c, 0xd8, 0x3c, 0xc9, 0x1a, 0x17, 0x71, 0xe6, 0x34, 0x34, 0xc0, 0x2d, 0x00, 0xe7, 0x45,
|
||||
0xe0, 0x66, 0xdb, 0xc0, 0x25, 0x00, 0x3e, 0x03, 0x4d, 0x25, 0x68, 0x7a, 0xc6, 0x9e, 0x73, 0xa7,
|
||||
0xa9, 0x15, 0xfb, 0x08, 0x6d, 0xbf, 0x88, 0x7f, 0x0c, 0x71, 0xa6, 0xd4, 0xc8, 0x64, 0x97, 0xea,
|
||||
0x14, 0x1e, 0xbc, 0x61, 0x82, 0x23, 0x50, 0xe7, 0xe3, 0x1f, 0x68, 0x20, 0x1d, 0x5b, 0x73, 0x1e,
|
||||
0xde, 0xd9, 0x05, 0x33, 0x83, 0x08, 0x93, 0xcb, 0xe1, 0x4f, 0x92, 0xb2, 0xac, 0x01, 0xfe, 0x3b,
|
||||
0x86, 0xba, 0x7e, 0xae, 0x49, 0xb0, 0x21, 0x83, 0xdf, 0x03, 0x9b, 0xcf, 0xc3, 0xdc, 0xe9, 0x80,
|
||||
0xff, 0xc3, 0xbc, 0x91, 0xf2, 0xbc, 0xe0, 0xc1, 0x25, 0x25, 0x3c, 0x00, 0xf5, 0x30, 0x5d, 0x62,
|
||||
0xc5, 0x9c, 0x56, 0xcf, 0xea, 0x37, 0x7d, 0x90, 0x9d, 0xe1, 0x54, 0x7b, 0xb0, 0x89, 0x1c, 0xfc,
|
||||
0x52, 0x03, 0x0f, 0xb6, 0x5e, 0x85, 0x48, 0x38, 0x13, 0xf4, 0xad, 0x3c, 0x8b, 0x8f, 0x41, 0x83,
|
||||
0xcc, 0xe7, 0xfc, 0x92, 0xe6, 0x2f, 0xa3, 0xe9, 0xdf, 0x37, 0x3c, 0x8d, 0x41, 0xee, 0xc6, 0x45,
|
||||
0x1c, 0x5e, 0x80, 0xba, 0x90, 0x44, 0x2a, 0x61, 0xa6, 0xfc, 0xe1, 0xeb, 0x4d, 0xf9, 0x53, 0x8d,
|
||||
0xc9, 0xaf, 0x85, 0xa9, 0x50, 0x73, 0x89, 0x0d, 0x0f, 0xec, 0x82, 0xbd, 0x84, 0xc8, 0x60, 0xaa,
|
||||
0x27, 0x79, 0xdf, 0xb7, 0xd7, 0xab, 0xee, 0xde, 0x45, 0xe6, 0xc0, 0xb9, 0x1f, 0x9e, 0x00, 0x5b,
|
||||
0xff, 0x3c, 0x5b, 0x26, 0xc5, 0xf8, 0x76, 0x32, 0x21, 0x2f, 0x0a, 0xe7, 0xcd, 0xb6, 0x81, 0xcb,
|
||||
0x64, 0xf8, 0xab, 0x05, 0xda, 0x44, 0x85, 0x91, 0x1c, 0x30, 0xc6, 0xa5, 0x1e, 0x24, 0xe1, 0xd4,
|
||||
0x7b, 0xd5, 0x7e, 0xeb, 0x78, 0x88, 0xfe, 0x6d, 0xfb, 0xa2, 0x5b, 0x3a, 0xa3, 0xc1, 0x0e, 0xcf,
|
||||
0x90, 0xc9, 0x74, 0xe9, 0x3b, 0x46, 0xa8, 0xf6, 0x6e, 0x18, 0xdf, 0x2a, 0xdc, 0xf9, 0x02, 0xbc,
|
||||
0xff, 0x4a, 0x12, 0xd8, 0x06, 0xd5, 0x19, 0x5d, 0xe6, 0x2d, 0xc4, 0xd9, 0x2f, 0x7c, 0x0f, 0xec,
|
||||
0x2d, 0xc8, 0x5c, 0x51, 0xdd, 0x0e, 0x1b, 0xe7, 0xc6, 0xe3, 0x7b, 0x27, 0xd6, 0xc1, 0x1f, 0x16,
|
||||
0xb8, 0xbf, 0x75, 0xb8, 0x45, 0x44, 0x2f, 0xe1, 0x08, 0x34, 0xd2, 0x7c, 0x49, 0x6a, 0x8e, 0xd6,
|
||||
0x31, 0x7a, 0xed, 0xcb, 0x69, 0x94, 0xdf, 0xca, 0x5a, 0x6d, 0x0c, 0x5c, 0x70, 0xc1, 0x6f, 0xf5,
|
||||
0x4a, 0xd3, 0xb7, 0x37, 0x0b, 0xd3, 0x7b, 0x43, 0xd1, 0xfc, 0x7d, 0xb3, 0xc3, 0xb4, 0x85, 0x37,
|
||||
0x74, 0xfe, 0xe1, 0xd5, 0xb5, 0x5b, 0x79, 0x71, 0xed, 0x56, 0x5e, 0x5e, 0xbb, 0x95, 0x9f, 0xd7,
|
||||
0xae, 0x75, 0xb5, 0x76, 0xad, 0x17, 0x6b, 0xd7, 0x7a, 0xb9, 0x76, 0xad, 0x3f, 0xd7, 0xae, 0xf5,
|
||||
0xdb, 0x5f, 0x6e, 0xe5, 0xbb, 0x86, 0x21, 0xfe, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xf4, 0xc2, 0x6f,
|
||||
0x1b, 0x71, 0x07, 0x00, 0x00,
|
||||
// 840 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcf, 0x6f, 0x1b, 0x45,
|
||||
0x14, 0xf6, 0xd6, 0x8e, 0xed, 0x1d, 0x47, 0xd4, 0x1d, 0x40, 0x5a, 0x59, 0x68, 0x6d, 0x72, 0x40,
|
||||
0x41, 0x6a, 0x66, 0x49, 0x04, 0x55, 0x54, 0x71, 0xc9, 0x92, 0x08, 0x45, 0x48, 0x4d, 0x34, 0xad,
|
||||
0x51, 0xe1, 0x80, 0x34, 0xde, 0x9d, 0xda, 0x8b, 0xbd, 0x33, 0xcb, 0xce, 0x8c, 0x83, 0x6f, 0x88,
|
||||
0x2b, 0x17, 0xfe, 0x27, 0x2e, 0x39, 0xf6, 0xd8, 0x53, 0x44, 0xcc, 0x99, 0x7f, 0x20, 0x27, 0x34,
|
||||
0xb3, 0xb3, 0x5e, 0x93, 0x34, 0xd0, 0x46, 0x3d, 0xed, 0xbc, 0x1f, 0xdf, 0xf7, 0xde, 0x7c, 0x6f,
|
||||
0xdf, 0x80, 0xa3, 0xe9, 0xbe, 0x40, 0x09, 0x0f, 0xa6, 0x6a, 0x44, 0x73, 0x46, 0x25, 0x15, 0xc1,
|
||||
0x9c, 0xb2, 0x98, 0xe7, 0x81, 0x0d, 0x90, 0x2c, 0x09, 0x48, 0x9c, 0x26, 0x42, 0x24, 0x9c, 0x05,
|
||||
0xf3, 0xdd, 0x11, 0x95, 0x64, 0x37, 0x18, 0x53, 0x46, 0x73, 0x22, 0x69, 0x8c, 0xb2, 0x9c, 0x4b,
|
||||
0x0e, 0x3f, 0x2a, 0xb2, 0x11, 0xc9, 0x12, 0xb4, 0xca, 0x46, 0x36, 0xbb, 0xb7, 0x33, 0x4e, 0xe4,
|
||||
0x44, 0x8d, 0x50, 0xc4, 0xd3, 0x60, 0xcc, 0xc7, 0x3c, 0x30, 0xa0, 0x91, 0x7a, 0x61, 0x2c, 0x63,
|
||||
0x98, 0x53, 0x41, 0xd6, 0x7b, 0xb8, 0x5e, 0x5a, 0xc9, 0x09, 0x65, 0x32, 0x89, 0x88, 0x2c, 0xea,
|
||||
0x5f, 0x2f, 0xdd, 0xfb, 0xbc, 0xca, 0x4e, 0x49, 0x34, 0x49, 0x18, 0xcd, 0x17, 0x41, 0x36, 0x1d,
|
||||
0x6b, 0x87, 0x08, 0x52, 0x2a, 0xc9, 0xeb, 0x50, 0xc1, 0x6d, 0xa8, 0x5c, 0x31, 0x99, 0xa4, 0xf4,
|
||||
0x06, 0xe0, 0xd1, 0xff, 0x01, 0x44, 0x34, 0xa1, 0x29, 0xb9, 0x8e, 0xdb, 0xfa, 0xbb, 0x09, 0xba,
|
||||
0x07, 0xa5, 0x22, 0x98, 0xfe, 0xa4, 0xa8, 0x90, 0x30, 0x04, 0x75, 0x95, 0xc4, 0x9e, 0x33, 0x70,
|
||||
0xb6, 0xdd, 0xf0, 0xb3, 0xf3, 0x8b, 0x7e, 0x6d, 0x79, 0xd1, 0xaf, 0x0f, 0x8f, 0x0f, 0xaf, 0x2e,
|
||||
0xfa, 0x1f, 0xdf, 0x56, 0x48, 0x2e, 0x32, 0x2a, 0xd0, 0xf0, 0xf8, 0x10, 0x6b, 0x30, 0x7c, 0x0e,
|
||||
0x1a, 0xd3, 0x84, 0xc5, 0xde, 0xbd, 0x81, 0xb3, 0xdd, 0xd9, 0x7b, 0x84, 0xaa, 0x09, 0xac, 0x60,
|
||||
0x28, 0x9b, 0x8e, 0xb5, 0x43, 0x20, 0x2d, 0x03, 0x9a, 0xef, 0xa2, 0xaf, 0x73, 0xae, 0xb2, 0x6f,
|
||||
0x69, 0xae, 0x9b, 0xf9, 0x26, 0x61, 0x71, 0xb8, 0x69, 0x8b, 0x37, 0xb4, 0x85, 0x0d, 0x23, 0x9c,
|
||||
0x80, 0x76, 0x4e, 0x05, 0x57, 0x79, 0x44, 0xbd, 0xba, 0x61, 0x7f, 0xfc, 0xf6, 0xec, 0xd8, 0x32,
|
||||
0x84, 0x5d, 0x5b, 0xa1, 0x5d, 0x7a, 0xf0, 0x8a, 0x1d, 0x7e, 0x01, 0x3a, 0x42, 0x8d, 0xca, 0x80,
|
||||
0xd7, 0x30, 0x7a, 0xbc, 0x6f, 0x01, 0x9d, 0xa7, 0x55, 0x08, 0xaf, 0xe7, 0xc1, 0x01, 0x68, 0x30,
|
||||
0x92, 0x52, 0x6f, 0xc3, 0xe4, 0xaf, 0xae, 0xf0, 0x84, 0xa4, 0x14, 0x9b, 0x08, 0x0c, 0x80, 0xab,
|
||||
0xbf, 0x22, 0x23, 0x11, 0xf5, 0x9a, 0x26, 0xed, 0x81, 0x4d, 0x73, 0x9f, 0x94, 0x01, 0x5c, 0xe5,
|
||||
0xc0, 0x2f, 0x81, 0xcb, 0x33, 0x3d, 0xb8, 0x84, 0x33, 0xaf, 0x65, 0x00, 0x7e, 0x09, 0x38, 0x29,
|
||||
0x03, 0x57, 0xeb, 0x06, 0xae, 0x00, 0xf0, 0x19, 0x68, 0x2b, 0x41, 0xf3, 0x63, 0xf6, 0x82, 0x7b,
|
||||
0x6d, 0xa3, 0xd8, 0x27, 0x68, 0x7d, 0x23, 0xfe, 0xf5, 0x13, 0x6b, 0xa5, 0x86, 0x36, 0xbb, 0x52,
|
||||
0xa7, 0xf4, 0xe0, 0x15, 0x13, 0x1c, 0x82, 0x26, 0x1f, 0xfd, 0x48, 0x23, 0xe9, 0xb9, 0x86, 0x73,
|
||||
0xe7, 0xd6, 0x29, 0xd8, 0x7f, 0x10, 0x61, 0x72, 0x76, 0xf4, 0xb3, 0xa4, 0x4c, 0x0f, 0x20, 0x7c,
|
||||
0xcf, 0x52, 0x37, 0x4f, 0x0c, 0x09, 0xb6, 0x64, 0xf0, 0x07, 0xe0, 0xf2, 0x59, 0x5c, 0x38, 0x3d,
|
||||
0x70, 0x17, 0xe6, 0x95, 0x94, 0x27, 0x25, 0x0f, 0xae, 0x28, 0xe1, 0x16, 0x68, 0xc6, 0xf9, 0x02,
|
||||
0x2b, 0xe6, 0x75, 0x06, 0xce, 0x76, 0x3b, 0x04, 0xba, 0x87, 0x43, 0xe3, 0xc1, 0x36, 0x02, 0x9f,
|
||||
0x83, 0x16, 0xcf, 0xb4, 0x18, 0xc2, 0xdb, 0xbc, 0x4b, 0x07, 0xf7, 0x6d, 0x07, 0xad, 0x93, 0x82,
|
||||
0x05, 0x97, 0x74, 0x5b, 0xbf, 0x36, 0xc0, 0x83, 0xb5, 0x7d, 0x13, 0x19, 0x67, 0x82, 0xbe, 0x93,
|
||||
0x85, 0xfb, 0x14, 0xb4, 0xc8, 0x6c, 0xc6, 0xcf, 0x68, 0xb1, 0x73, 0xed, 0xaa, 0x89, 0x83, 0xc2,
|
||||
0x8d, 0xcb, 0x38, 0x3c, 0x05, 0x4d, 0x21, 0x89, 0x54, 0xc2, 0xee, 0xcf, 0xc3, 0x37, 0xdb, 0x9f,
|
||||
0xa7, 0x06, 0x53, 0x08, 0x86, 0xa9, 0x50, 0x33, 0x89, 0x2d, 0x0f, 0xec, 0x83, 0x8d, 0x8c, 0xc8,
|
||||
0x68, 0x62, 0x76, 0x64, 0x33, 0x74, 0x97, 0x17, 0xfd, 0x8d, 0x53, 0xed, 0xc0, 0x85, 0x1f, 0xee,
|
||||
0x03, 0xd7, 0x1c, 0x9e, 0x2d, 0xb2, 0x72, 0x31, 0x7a, 0x7a, 0x44, 0xa7, 0xa5, 0xf3, 0x6a, 0xdd,
|
||||
0xc0, 0x55, 0x32, 0xfc, 0xcd, 0x01, 0x5d, 0xa2, 0xe2, 0x44, 0x1e, 0x30, 0xc6, 0x25, 0x29, 0xa6,
|
||||
0xd2, 0x1c, 0xd4, 0xb7, 0x3b, 0x7b, 0x47, 0xe8, 0xbf, 0xde, 0x75, 0x74, 0x43, 0x67, 0x74, 0x70,
|
||||
0x8d, 0xe7, 0x88, 0xc9, 0x7c, 0x11, 0x7a, 0x56, 0xa8, 0xee, 0xf5, 0x30, 0xbe, 0x51, 0xb8, 0xf7,
|
||||
0x15, 0xf8, 0xf0, 0xb5, 0x24, 0xb0, 0x0b, 0xea, 0x53, 0xba, 0x28, 0x46, 0x88, 0xf5, 0x11, 0x7e,
|
||||
0x00, 0x36, 0xe6, 0x64, 0xa6, 0xa8, 0x19, 0x87, 0x8b, 0x0b, 0xe3, 0xf1, 0xbd, 0x7d, 0x67, 0xeb,
|
||||
0x0f, 0x07, 0xdc, 0x5f, 0x6b, 0x6e, 0x9e, 0xd0, 0x33, 0x38, 0x04, 0xad, 0xbc, 0x78, 0x7e, 0x0d,
|
||||
0x47, 0x67, 0x0f, 0xbd, 0xf1, 0xe5, 0x0c, 0x2a, 0xec, 0xe8, 0x51, 0x5b, 0x03, 0x97, 0x5c, 0xf0,
|
||||
0x3b, 0xf3, 0x58, 0x9a, 0xdb, 0xdb, 0xa7, 0x38, 0x78, 0x4b, 0xd1, 0xc2, 0x4d, 0xfb, 0x3a, 0x1a,
|
||||
0x0b, 0xaf, 0xe8, 0xc2, 0x9d, 0xf3, 0x4b, 0xbf, 0xf6, 0xf2, 0xd2, 0xaf, 0xbd, 0xba, 0xf4, 0x6b,
|
||||
0xbf, 0x2c, 0x7d, 0xe7, 0x7c, 0xe9, 0x3b, 0x2f, 0x97, 0xbe, 0xf3, 0x6a, 0xe9, 0x3b, 0x7f, 0x2e,
|
||||
0x7d, 0xe7, 0xf7, 0xbf, 0xfc, 0xda, 0xf7, 0x2d, 0x4b, 0xfc, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x9a, 0x46, 0xfc, 0x70, 0xcb, 0x07, 0x00, 0x00,
|
||||
}
|
||||
|
@@ -60,7 +60,8 @@ message AdmissionRequest {
|
||||
// +optional
|
||||
optional string namespace = 6;
|
||||
|
||||
// Operation is the operation being performed
|
||||
// Operation is the operation being performed. This may be different than the operation
|
||||
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
|
||||
optional string operation = 7;
|
||||
|
||||
// UserInfo is information about the requesting user
|
||||
@@ -78,6 +79,14 @@ message AdmissionRequest {
|
||||
// Defaults to false.
|
||||
// +optional
|
||||
optional bool dryRun = 11;
|
||||
|
||||
// Options is the operation option structure of the operation being performed.
|
||||
// e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
|
||||
// different than the options the caller provided. e.g. for a patch request the performed
|
||||
// Operation might be a CREATE, in which case the Options will a
|
||||
// `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
|
||||
// +optional
|
||||
optional k8s.io.apimachinery.pkg.runtime.RawExtension options = 12;
|
||||
}
|
||||
|
||||
// AdmissionResponse describes an admission response.
|
||||
|
@@ -61,7 +61,8 @@ type AdmissionRequest struct {
|
||||
// Namespace is the namespace associated with the request (if any).
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty" protobuf:"bytes,6,opt,name=namespace"`
|
||||
// Operation is the operation being performed
|
||||
// Operation is the operation being performed. This may be different than the operation
|
||||
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
|
||||
Operation Operation `json:"operation" protobuf:"bytes,7,opt,name=operation"`
|
||||
// UserInfo is information about the requesting user
|
||||
UserInfo authenticationv1.UserInfo `json:"userInfo" protobuf:"bytes,8,opt,name=userInfo"`
|
||||
@@ -75,6 +76,13 @@ type AdmissionRequest struct {
|
||||
// Defaults to false.
|
||||
// +optional
|
||||
DryRun *bool `json:"dryRun,omitempty" protobuf:"varint,11,opt,name=dryRun"`
|
||||
// Options is the operation option structure of the operation being performed.
|
||||
// e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
|
||||
// different than the options the caller provided. e.g. for a patch request the performed
|
||||
// Operation might be a CREATE, in which case the Options will a
|
||||
// `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
|
||||
// +optional
|
||||
Options runtime.RawExtension `json:"options,omitempty" protobuf:"bytes,12,opt,name=options"`
|
||||
}
|
||||
|
||||
// AdmissionResponse describes an admission response.
|
||||
|
@@ -35,11 +35,12 @@ var map_AdmissionRequest = map[string]string{
|
||||
"subResource": "SubResource is the name of the subresource being requested. This is a different resource, scoped to the parent resource, but it may have a different kind. For instance, /pods has the resource \"pods\" and the kind \"Pod\", while /pods/foo/status has the resource \"pods\", the sub resource \"status\", and the kind \"Pod\" (because status operates on pods). The binding resource for a pod though may be /pods/foo/binding, which has resource \"pods\", subresource \"binding\", and kind \"Binding\".",
|
||||
"name": "Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and rely on the server to generate the name. If that is the case, this method will return the empty string.",
|
||||
"namespace": "Namespace is the namespace associated with the request (if any).",
|
||||
"operation": "Operation is the operation being performed",
|
||||
"operation": "Operation is the operation being performed. This may be different than the operation requested. e.g. a patch can result in either a CREATE or UPDATE Operation.",
|
||||
"userInfo": "UserInfo is information about the requesting user",
|
||||
"object": "Object is the object from the incoming request prior to default values being applied",
|
||||
"oldObject": "OldObject is the existing object. Only populated for UPDATE requests.",
|
||||
"dryRun": "DryRun indicates that modifications will definitely not be persisted for this request. Defaults to false.",
|
||||
"options": "Options is the operation option structure of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be different than the options the caller provided. e.g. for a patch request the performed Operation might be a CREATE, in which case the Options will a `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.",
|
||||
}
|
||||
|
||||
func (AdmissionRequest) SwaggerDoc() map[string]string {
|
||||
|
@@ -38,6 +38,7 @@ func (in *AdmissionRequest) DeepCopyInto(out *AdmissionRequest) {
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
in.Options.DeepCopyInto(&out.Options)
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -46,7 +46,7 @@ message ConversionRequest {
|
||||
// ConversionResponse describes a conversion response.
|
||||
message ConversionResponse {
|
||||
// `uid` is an identifier for the individual request/response.
|
||||
// This should be copied over from the corresponding AdmissionRequest.
|
||||
// This should be copied over from the corresponding ConversionRequest.
|
||||
optional string uid = 1;
|
||||
|
||||
// `convertedObjects` is the list of converted version of `request.objects` if the `result` is successful otherwise empty.
|
||||
|
@@ -443,7 +443,7 @@ type ConversionRequest struct {
|
||||
// ConversionResponse describes a conversion response.
|
||||
type ConversionResponse struct {
|
||||
// `uid` is an identifier for the individual request/response.
|
||||
// This should be copied over from the corresponding AdmissionRequest.
|
||||
// This should be copied over from the corresponding ConversionRequest.
|
||||
UID types.UID `json:"uid" protobuf:"bytes,1,name=uid"`
|
||||
// `convertedObjects` is the list of converted version of `request.objects` if the `result` is successful otherwise empty.
|
||||
// The webhook is expected to set apiVersion of these objects to the ConversionRequest.desiredAPIVersion. The list
|
||||
|
@@ -34,6 +34,7 @@ type attributesRecord struct {
|
||||
resource schema.GroupVersionResource
|
||||
subresource string
|
||||
operation Operation
|
||||
options runtime.Object
|
||||
dryRun bool
|
||||
object runtime.Object
|
||||
oldObject runtime.Object
|
||||
@@ -45,7 +46,7 @@ type attributesRecord struct {
|
||||
annotationsLock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewAttributesRecord(object runtime.Object, oldObject runtime.Object, kind schema.GroupVersionKind, namespace, name string, resource schema.GroupVersionResource, subresource string, operation Operation, dryRun bool, userInfo user.Info) Attributes {
|
||||
func NewAttributesRecord(object runtime.Object, oldObject runtime.Object, kind schema.GroupVersionKind, namespace, name string, resource schema.GroupVersionResource, subresource string, operation Operation, operationOptions runtime.Object, dryRun bool, userInfo user.Info) Attributes {
|
||||
return &attributesRecord{
|
||||
kind: kind,
|
||||
namespace: namespace,
|
||||
@@ -53,6 +54,7 @@ func NewAttributesRecord(object runtime.Object, oldObject runtime.Object, kind s
|
||||
resource: resource,
|
||||
subresource: subresource,
|
||||
operation: operation,
|
||||
options: operationOptions,
|
||||
dryRun: dryRun,
|
||||
object: object,
|
||||
oldObject: oldObject,
|
||||
@@ -84,6 +86,10 @@ func (record *attributesRecord) GetOperation() Operation {
|
||||
return record.operation
|
||||
}
|
||||
|
||||
func (record *attributesRecord) GetOperationOptions() runtime.Object {
|
||||
return record.options
|
||||
}
|
||||
|
||||
func (record *attributesRecord) IsDryRun() bool {
|
||||
return record.dryRun
|
||||
}
|
||||
|
@@ -64,7 +64,7 @@ func (h fakeHandler) Handles(o Operation) bool {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
@@ -63,6 +64,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
||||
name string
|
||||
ns string
|
||||
operation Operation
|
||||
options runtime.Object
|
||||
chain chainAdmissionHandler
|
||||
accept bool
|
||||
calls map[string]bool
|
||||
@@ -71,6 +73,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
||||
name: "all accept",
|
||||
ns: sysns,
|
||||
operation: Create,
|
||||
options: &metav1.CreateOptions{},
|
||||
chain: []Interface{
|
||||
makeHandler("a", true, Update, Delete, Create),
|
||||
makeHandler("b", true, Delete, Create),
|
||||
@@ -83,6 +86,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
||||
name: "ignore handler",
|
||||
ns: otherns,
|
||||
operation: Create,
|
||||
options: &metav1.CreateOptions{},
|
||||
chain: []Interface{
|
||||
makeHandler("a", true, Update, Delete, Create),
|
||||
makeHandler("b", false, Delete),
|
||||
@@ -95,6 +99,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
||||
name: "ignore all",
|
||||
ns: sysns,
|
||||
operation: Connect,
|
||||
options: nil,
|
||||
chain: []Interface{
|
||||
makeHandler("a", true, Update, Delete, Create),
|
||||
makeHandler("b", false, Delete),
|
||||
@@ -107,6 +112,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
||||
name: "reject one",
|
||||
ns: otherns,
|
||||
operation: Delete,
|
||||
options: &metav1.DeleteOptions{},
|
||||
chain: []Interface{
|
||||
makeHandler("a", true, Update, Delete, Create),
|
||||
makeHandler("b", false, Delete),
|
||||
@@ -119,7 +125,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Logf("testcase = %s", test.name)
|
||||
// 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)
|
||||
if accepted != test.accept {
|
||||
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
|
||||
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)
|
||||
if accepted != test.accept {
|
||||
t.Errorf("unexpected result of validate call: %v\n", accepted)
|
||||
|
@@ -36,6 +36,7 @@ func TestNewForbidden(t *testing.T) {
|
||||
schema.GroupVersionResource{Group: "foo", Version: "bar", Resource: "baz"},
|
||||
"",
|
||||
Create,
|
||||
nil,
|
||||
false,
|
||||
nil)
|
||||
err := errors.New("some error")
|
||||
|
@@ -41,6 +41,8 @@ type Attributes interface {
|
||||
GetSubresource() string
|
||||
// GetOperation is the operation being performed
|
||||
GetOperation() Operation
|
||||
// GetOperationOptions is the options for the operation being performed
|
||||
GetOperationOptions() runtime.Object
|
||||
// IsDryRun indicates that modifications will definitely not be persisted for this request. This is to prevent
|
||||
// admission controllers with side effects and a method of reconciliation from being overwhelmed.
|
||||
// However, a value of false for this does not mean that the modification will be persisted, because it
|
||||
|
@@ -20,6 +20,8 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
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/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
|
@@ -21,6 +21,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
)
|
||||
@@ -28,7 +30,7 @@ import (
|
||||
var (
|
||||
kind = schema.GroupVersionKind{Group: "kgroup", Version: "kversion", Kind: "kind"}
|
||||
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) {
|
||||
@@ -85,6 +87,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
name string
|
||||
ns string
|
||||
operation admission.Operation
|
||||
options runtime.Object
|
||||
handler admission.Interface
|
||||
admit, validate bool
|
||||
}
|
||||
@@ -93,6 +96,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
"both-interfaces-admit-and-validate",
|
||||
"some-ns",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true, true},
|
||||
true, true,
|
||||
},
|
||||
@@ -100,6 +104,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
"both-interfaces-dont-admit",
|
||||
"some-ns",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false, true},
|
||||
false, true,
|
||||
},
|
||||
@@ -107,6 +112,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
"both-interfaces-admit-dont-validate",
|
||||
"some-ns",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true, false},
|
||||
true, false,
|
||||
},
|
||||
@@ -114,6 +120,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
"validate-interfaces-validate",
|
||||
"some-ns",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
&validatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true},
|
||||
true, true,
|
||||
},
|
||||
@@ -121,6 +128,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
"validate-interfaces-dont-validate",
|
||||
"some-ns",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
&validatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false},
|
||||
true, false,
|
||||
},
|
||||
@@ -128,6 +136,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
"mutating-interfaces-admit",
|
||||
"some-ns",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
&mutatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), true},
|
||||
true, true,
|
||||
},
|
||||
@@ -135,6 +144,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
"mutating-interfaces-dont-admit",
|
||||
"some-ns",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
&mutatingFakeHandler{admission.NewHandler(admission.Create, admission.Update), false},
|
||||
false, true,
|
||||
},
|
||||
@@ -144,7 +154,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
h := WithMetrics(test.handler, Metrics.ObserveAdmissionController, test.name)
|
||||
|
||||
// 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 {
|
||||
t.Errorf("expected admit to succeed, but failed: %v", err)
|
||||
continue
|
||||
@@ -169,7 +179,7 @@ func TestWithMetrics(t *testing.T) {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("expected admit to succeed, but failed: %v", err)
|
||||
continue
|
||||
|
@@ -21,7 +21,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -104,7 +104,7 @@ func TestAccessReviewCheckOnMissingNamespace(t *testing.T) {
|
||||
}
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -124,7 +124,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
actions := ""
|
||||
for _, action := range mockClient.Actions() {
|
||||
@@ -134,19 +134,19 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Expected error rejecting creates in a namespace when it is missing")
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Expected error rejecting updates in a namespace when it is missing")
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
@@ -166,7 +166,7 @@ func TestAdmissionNamespaceActive(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
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 {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -187,31 +187,31 @@ func TestAdmissionNamespaceTerminating(t *testing.T) {
|
||||
|
||||
pod := newPod(namespace)
|
||||
// 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 {
|
||||
t.Errorf("Expected error rejecting creates in a namespace when it is terminating")
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Expected an error that this namespace can never be deleted")
|
||||
}
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Did not expect an error %v", err)
|
||||
}
|
||||
@@ -238,7 +238,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
|
||||
pod := newPod(namespace)
|
||||
// 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 {
|
||||
t.Errorf("Unexpected error rejecting creates in an active namespace")
|
||||
}
|
||||
@@ -248,7 +248,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
getCalls = 0
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Expected namespace deletion to be allowed")
|
||||
}
|
||||
@@ -261,7 +261,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
phases[namespace] = v1.NamespaceTerminating
|
||||
|
||||
// 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 {
|
||||
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)
|
||||
|
||||
// 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 {
|
||||
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)
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Expected no live lookup of the namespace at t=forceLiveLookupTTL+1ms, got %d", getCalls)
|
||||
}
|
||||
|
@@ -122,7 +122,7 @@ func TestDispatch(t *testing.T) {
|
||||
plugin: &Plugin{},
|
||||
}
|
||||
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,
|
||||
VersionedObject: test.in,
|
||||
}
|
||||
|
@@ -75,27 +75,27 @@ func TestGetNamespaceLabels(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
}
|
||||
@@ -117,7 +117,7 @@ func TestNotExemptClusterScopedResource(t *testing.T) {
|
||||
hook := ®istrationv1beta1.Webhook{
|
||||
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{}
|
||||
matches, err := matcher.MatchNamespaceSelector(hook, attr)
|
||||
if err != nil {
|
||||
|
@@ -68,6 +68,9 @@ func CreateAdmissionReview(attr *generic.VersionedAttributes) admissionv1beta1.A
|
||||
Object: attr.VersionedOldObject,
|
||||
},
|
||||
DryRun: &dryRun,
|
||||
Options: runtime.RawExtension{
|
||||
Object: attr.GetOperationOptions(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,8 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//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/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
|
@@ -21,6 +21,8 @@ import (
|
||||
"testing"
|
||||
|
||||
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/util/sets"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
@@ -33,37 +35,40 @@ type ruleTest struct {
|
||||
}
|
||||
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(
|
||||
nil, nil,
|
||||
schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource},
|
||||
"ns", name,
|
||||
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
|
||||
operation,
|
||||
operationOptions,
|
||||
false,
|
||||
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(
|
||||
nil, nil,
|
||||
schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource},
|
||||
"ns", name,
|
||||
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
|
||||
operation,
|
||||
operationOptions,
|
||||
false,
|
||||
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(
|
||||
nil, nil,
|
||||
schema.GroupVersionKind{Group: group, Version: version, Kind: "k" + resource},
|
||||
"", name,
|
||||
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
|
||||
operation,
|
||||
operationOptions,
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
@@ -82,7 +87,7 @@ func TestGroup(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
"exact": {
|
||||
@@ -92,12 +97,12 @@ func TestGroup(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g1", "v", "r", "", "name", admission.Create),
|
||||
a("g2", "v2", "r3", "", "name", admission.Create),
|
||||
a("g1", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g2", "v2", "r3", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g3", "v", "r", "", "name", admission.Create),
|
||||
a("g4", "v", "r", "", "name", admission.Create),
|
||||
a("g3", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g4", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
}
|
||||
@@ -127,7 +132,7 @@ func TestVersion(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
"exact": {
|
||||
@@ -137,12 +142,12 @@ func TestVersion(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g1", "v1", "r", "", "name", admission.Create),
|
||||
a("g2", "v2", "r", "", "name", admission.Create),
|
||||
a("g1", "v1", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g2", "v2", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g1", "v3", "r", "", "name", admission.Create),
|
||||
a("g2", "v4", "r", "", "name", admission.Create),
|
||||
a("g1", "v3", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g2", "v4", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
}
|
||||
@@ -167,65 +172,65 @@ func TestOperation(t *testing.T) {
|
||||
"wildcard": {
|
||||
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.OperationAll}},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Update),
|
||||
a("g", "v", "r", "", "name", admission.Delete),
|
||||
a("g", "v", "r", "", "name", admission.Connect),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Connect, nil),
|
||||
),
|
||||
},
|
||||
"create": {
|
||||
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Create}},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Update),
|
||||
a("g", "v", "r", "", "name", admission.Delete),
|
||||
a("g", "v", "r", "", "name", admission.Connect),
|
||||
a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Connect, nil),
|
||||
),
|
||||
},
|
||||
"update": {
|
||||
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Update}},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Update),
|
||||
a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Delete),
|
||||
a("g", "v", "r", "", "name", admission.Connect),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Connect, nil),
|
||||
),
|
||||
},
|
||||
"delete": {
|
||||
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Delete}},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Delete),
|
||||
a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Update),
|
||||
a("g", "v", "r", "", "name", admission.Connect),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Connect, nil),
|
||||
),
|
||||
},
|
||||
"connect": {
|
||||
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Connect}},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Connect),
|
||||
a("g", "v", "r", "", "name", admission.Connect, nil),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Update),
|
||||
a("g", "v", "r", "", "name", admission.Delete),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
|
||||
),
|
||||
},
|
||||
"multiple": {
|
||||
rule: adreg.RuleWithOperations{Operations: []adreg.OperationType{adreg.Update, adreg.Delete}},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Update),
|
||||
a("g", "v", "r", "", "name", admission.Delete),
|
||||
a("g", "v", "r", "", "name", admission.Update, &metav1.UpdateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Delete, &metav1.DeleteOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Connect),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g", "v", "r", "", "name", admission.Connect, nil),
|
||||
),
|
||||
},
|
||||
}
|
||||
@@ -254,12 +259,12 @@ func TestResource(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("2", "v", "r2", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g", "v", "r", "exec", "name", admission.Create),
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create),
|
||||
a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
"r & subresources": {
|
||||
@@ -269,12 +274,12 @@ func TestResource(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "exec", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("2", "v", "r2", "", "name", admission.Create),
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create),
|
||||
a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
"r & subresources or r2": {
|
||||
@@ -284,12 +289,12 @@ func TestResource(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("g", "v", "r", "exec", "name", admission.Create),
|
||||
a("2", "v", "r2", "", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create),
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
"proxy or exec": {
|
||||
@@ -299,14 +304,14 @@ func TestResource(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
a("g", "v", "r", "exec", "name", admission.Create),
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create),
|
||||
a("2", "v", "r3", "proxy", "name", admission.Create),
|
||||
a("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r2", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r3", "proxy", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
a("g", "v", "r", "", "name", admission.Create),
|
||||
a("2", "v", "r2", "", "name", admission.Create),
|
||||
a("2", "v", "r4", "scale", "name", admission.Create),
|
||||
a("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r2", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
a("2", "v", "r4", "scale", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
}
|
||||
@@ -339,16 +344,16 @@ func TestScope(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create),
|
||||
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create),
|
||||
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create),
|
||||
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create),
|
||||
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
namespacedAttributes("g", "v", "r", "", "name", admission.Create),
|
||||
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create),
|
||||
namespacedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
"namespace scope": {
|
||||
@@ -359,16 +364,16 @@ func TestScope(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
namespacedAttributes("g", "v", "r", "", "name", admission.Create),
|
||||
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create),
|
||||
namespacedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(
|
||||
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create),
|
||||
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create),
|
||||
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create),
|
||||
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create),
|
||||
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
},
|
||||
"all scopes": {
|
||||
@@ -379,14 +384,14 @@ func TestScope(t *testing.T) {
|
||||
},
|
||||
},
|
||||
match: attrList(
|
||||
namespacedAttributes("g", "v", "r", "", "name", admission.Create),
|
||||
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create),
|
||||
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create),
|
||||
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create),
|
||||
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create),
|
||||
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create),
|
||||
namespacedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("g", "v", "r", "", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("g", "v", "r", "exec", "name", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
clusterScopedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("", "v1", "namespaces", "", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
namespacedAttributes("", "v1", "namespaces", "finalize", "ns", admission.Create, &metav1.CreateOptions{}),
|
||||
),
|
||||
noMatch: attrList(),
|
||||
},
|
||||
|
@@ -101,9 +101,10 @@ func newAttributesRecord(object metav1.Object, oldObject metav1.Object, kind sch
|
||||
Name: "webhook-test",
|
||||
UID: "webhook-test",
|
||||
}
|
||||
options := &metav1.UpdateOptions{}
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
|
@@ -106,6 +106,7 @@ func createHandler(r rest.NamedCreater, scope *RequestScope, admit admission.Int
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
options.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("CreateOptions"))
|
||||
|
||||
defaultGVK := scope.Kind
|
||||
original := r.New()
|
||||
@@ -128,7 +129,7 @@ func createHandler(r rest.NamedCreater, scope *RequestScope, admit admission.Int
|
||||
audit.LogRequestObject(ae, obj, scope.Resource, scope.Subresource, scope.Serializer)
|
||||
|
||||
userInfo, _ := request.UserFrom(ctx)
|
||||
admissionAttributes := admission.NewAttributesRecord(obj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
admissionAttributes := admission.NewAttributesRecord(obj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, options, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) {
|
||||
err = mutatingAdmission.Admit(admissionAttributes, scope)
|
||||
if err != nil {
|
||||
|
@@ -113,11 +113,12 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope *RequestSc
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
options.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("DeleteOptions"))
|
||||
|
||||
trace.Step("About to check admission control")
|
||||
if admit != nil && admit.Handles(admission.Delete) {
|
||||
userInfo, _ := request.UserFrom(ctx)
|
||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Delete, options, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||
if err := mutatingAdmission.Admit(attrs, scope); err != nil {
|
||||
scope.err(err, w, req)
|
||||
@@ -236,6 +237,8 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope *RequestSc
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
// For backwards compatibility, we need to allow existing clients to submit per group DeleteOptions
|
||||
// It is also allowed to pass a body with meta.k8s.io/v1.DeleteOptions
|
||||
defaultGVK := scope.Kind.GroupVersion().WithKind("DeleteOptions")
|
||||
obj, _, err := scope.Serializer.DecoderToVersion(s.Serializer, defaultGVK.GroupVersion()).Decode(body, &defaultGVK, options)
|
||||
if err != nil {
|
||||
@@ -262,11 +265,12 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope *RequestSc
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
options.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("DeleteOptions"))
|
||||
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
if admit != nil && admit.Handles(admission.Delete) {
|
||||
userInfo, _ := request.UserFrom(ctx)
|
||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, "", scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, "", scope.Resource, scope.Subresource, admission.Delete, options, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||
err = mutatingAdmission.Admit(attrs, scope)
|
||||
if err != nil {
|
||||
|
@@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
@@ -118,6 +118,7 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
options.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("PatchOptions"))
|
||||
|
||||
ae := request.AuditEventFrom(ctx)
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
@@ -151,6 +152,7 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac
|
||||
scope.Resource,
|
||||
scope.Subresource,
|
||||
admission.Create,
|
||||
patchToCreateOptions(options),
|
||||
dryrun.IsDryRun(options.DryRun),
|
||||
userInfo)
|
||||
staticUpdateAttributes := admission.NewAttributesRecord(
|
||||
@@ -162,6 +164,7 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac
|
||||
scope.Resource,
|
||||
scope.Subresource,
|
||||
admission.Update,
|
||||
patchToUpdateOptions(options),
|
||||
dryrun.IsDryRun(options.DryRun),
|
||||
userInfo,
|
||||
)
|
||||
@@ -489,9 +492,9 @@ func (p *patcher) applyPatch(_ context.Context, _, currentObject runtime.Object)
|
||||
return objToUpdate, nil
|
||||
}
|
||||
|
||||
func (p *patcher) admissionAttributes(ctx context.Context, updatedObject runtime.Object, currentObject runtime.Object, operation admission.Operation) admission.Attributes {
|
||||
func (p *patcher) admissionAttributes(ctx context.Context, updatedObject runtime.Object, currentObject runtime.Object, operation admission.Operation, operationOptions runtime.Object) admission.Attributes {
|
||||
userInfo, _ := request.UserFrom(ctx)
|
||||
return admission.NewAttributesRecord(updatedObject, currentObject, p.kind, p.namespace, p.name, p.resource, p.subresource, operation, p.dryRun, userInfo)
|
||||
return admission.NewAttributesRecord(updatedObject, currentObject, p.kind, p.namespace, p.name, p.resource, p.subresource, operation, operationOptions, p.dryRun, userInfo)
|
||||
}
|
||||
|
||||
// applyAdmission is called every time GuaranteedUpdate asks for the updated object,
|
||||
@@ -500,16 +503,19 @@ func (p *patcher) admissionAttributes(ctx context.Context, updatedObject runtime
|
||||
func (p *patcher) applyAdmission(ctx context.Context, patchedObject runtime.Object, currentObject runtime.Object) (runtime.Object, error) {
|
||||
p.trace.Step("About to check admission control")
|
||||
var operation admission.Operation
|
||||
var options runtime.Object
|
||||
if hasUID, err := hasUID(currentObject); err != nil {
|
||||
return nil, err
|
||||
} else if !hasUID {
|
||||
operation = admission.Create
|
||||
currentObject = nil
|
||||
options = patchToCreateOptions(p.options)
|
||||
} else {
|
||||
operation = admission.Update
|
||||
options = patchToUpdateOptions(p.options)
|
||||
}
|
||||
if p.admissionCheck != nil && p.admissionCheck.Handles(operation) {
|
||||
attributes := p.admissionAttributes(ctx, patchedObject, currentObject, operation)
|
||||
attributes := p.admissionAttributes(ctx, patchedObject, currentObject, operation, options)
|
||||
return patchedObject, p.admissionCheck.Admit(attributes, p.objectInterfaces)
|
||||
}
|
||||
return patchedObject, nil
|
||||
@@ -551,11 +557,8 @@ func (p *patcher) patchResource(ctx context.Context, scope *RequestScope) (runti
|
||||
wasCreated := false
|
||||
p.updatedObjectInfo = rest.DefaultUpdatedObjectInfo(nil, p.applyPatch, p.applyAdmission)
|
||||
result, err := finishRequest(p.timeout, func() (runtime.Object, error) {
|
||||
// TODO: Pass in UpdateOptions to override UpdateStrategy.AllowUpdateOnCreate
|
||||
options, err := patchToUpdateOptions(p.options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Pass in UpdateOptions to override UpdateStrategy.AllowUpdateOnCreate
|
||||
options := patchToUpdateOptions(p.options)
|
||||
updateObject, created, updateErr := p.restPatcher.Update(ctx, p.name, p.updatedObjectInfo, p.createValidation, p.updateValidation, p.forceAllowCreate, options)
|
||||
wasCreated = created
|
||||
return updateObject, updateErr
|
||||
@@ -600,12 +603,28 @@ func interpretStrategicMergePatchError(err error) error {
|
||||
}
|
||||
}
|
||||
|
||||
func patchToUpdateOptions(po *metav1.PatchOptions) (*metav1.UpdateOptions, error) {
|
||||
b, err := json.Marshal(po)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// patchToUpdateOptions creates an UpdateOptions with the same field values as the provided PatchOptions.
|
||||
func patchToUpdateOptions(po *metav1.PatchOptions) *metav1.UpdateOptions {
|
||||
if po == nil {
|
||||
return nil
|
||||
}
|
||||
uo := metav1.UpdateOptions{}
|
||||
err = json.Unmarshal(b, &uo)
|
||||
return &uo, err
|
||||
uo := &metav1.UpdateOptions{
|
||||
DryRun: po.DryRun,
|
||||
FieldManager: po.FieldManager,
|
||||
}
|
||||
uo.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("UpdateOptions"))
|
||||
return uo
|
||||
}
|
||||
|
||||
// patchToCreateOptions creates an CreateOptions with the same field values as the provided PatchOptions.
|
||||
func patchToCreateOptions(po *metav1.PatchOptions) *metav1.CreateOptions {
|
||||
if po == nil {
|
||||
return nil
|
||||
}
|
||||
co := &metav1.CreateOptions{
|
||||
DryRun: po.DryRun,
|
||||
FieldManager: po.FieldManager,
|
||||
}
|
||||
co.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("CreateOptions"))
|
||||
return co
|
||||
}
|
||||
|
@@ -137,14 +137,14 @@ func ConnectResource(connecter rest.Connecter, scope *RequestScope, admit admiss
|
||||
userInfo, _ := request.UserFrom(ctx)
|
||||
// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||
err = mutatingAdmission.Admit(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), scope)
|
||||
err = mutatingAdmission.Admit(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, nil, false, userInfo), scope)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
}
|
||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
||||
err = validatingAdmission.Validate(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), scope)
|
||||
err = validatingAdmission.Validate(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, nil, false, userInfo), scope)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
|
@@ -26,7 +26,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
fuzz "github.com/google/gofuzz"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
@@ -1000,3 +1002,89 @@ func (alwaysErrorTyper) ObjectKinds(runtime.Object) ([]schema.GroupVersionKind,
|
||||
func (alwaysErrorTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func TestUpdateToCreateOptions(t *testing.T) {
|
||||
f := fuzz.New()
|
||||
for i := 0; i < 100; i++ {
|
||||
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
|
||||
update := &metav1.UpdateOptions{}
|
||||
f.Fuzz(update)
|
||||
create := updateToCreateOptions(update)
|
||||
|
||||
b, err := json.Marshal(create)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal CreateOptions (%v): %v", err, create)
|
||||
}
|
||||
got := &metav1.UpdateOptions{}
|
||||
err = json.Unmarshal(b, &got)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to unmarshal UpdateOptions: %v", err)
|
||||
}
|
||||
got.TypeMeta = metav1.TypeMeta{}
|
||||
update.TypeMeta = metav1.TypeMeta{}
|
||||
if !reflect.DeepEqual(*update, *got) {
|
||||
t.Fatalf(`updateToCreateOptions round-trip failed:
|
||||
got: %#+v
|
||||
want: %#+v`, got, update)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatchToUpdateOptions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
converterFn func(po *metav1.PatchOptions) interface{}
|
||||
}{
|
||||
{
|
||||
name: "patchToUpdateOptions",
|
||||
converterFn: func(patch *metav1.PatchOptions) interface{} {
|
||||
return patchToUpdateOptions(patch)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "patchToCreateOptions",
|
||||
converterFn: func(patch *metav1.PatchOptions) interface{} {
|
||||
return patchToCreateOptions(patch)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
f := fuzz.New()
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
for i := 0; i < 100; i++ {
|
||||
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
|
||||
patch := &metav1.PatchOptions{}
|
||||
f.Fuzz(patch)
|
||||
converted := test.converterFn(patch)
|
||||
|
||||
b, err := json.Marshal(converted)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal converted object (%v): %v", err, converted)
|
||||
}
|
||||
got := &metav1.PatchOptions{}
|
||||
err = json.Unmarshal(b, &got)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to unmarshal converted object: %v", err)
|
||||
}
|
||||
|
||||
// Clear TypeMeta because we expect it to be different between the original and converted type
|
||||
got.TypeMeta = metav1.TypeMeta{}
|
||||
patch.TypeMeta = metav1.TypeMeta{}
|
||||
|
||||
// clear fields that we know belong in PatchOptions only
|
||||
patch.Force = nil
|
||||
|
||||
if !reflect.DeepEqual(*patch, *got) {
|
||||
t.Fatalf(`round-trip failed:
|
||||
got: %#+v
|
||||
want: %#+v`, got, converted)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -87,6 +87,7 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
options.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("UpdateOptions"))
|
||||
|
||||
s, err := negotiation.NegotiateInputSerializer(req, false, scope.Serializer)
|
||||
if err != nil {
|
||||
@@ -138,11 +139,11 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa
|
||||
return nil, fmt.Errorf("unexpected error when extracting UID from oldObj: %v", err.Error())
|
||||
} else if !isNotZeroObject {
|
||||
if mutatingAdmission.Handles(admission.Create) {
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), scope)
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, updateToCreateOptions(options), dryrun.IsDryRun(options.DryRun), userInfo), scope)
|
||||
}
|
||||
} else {
|
||||
if mutatingAdmission.Handles(admission.Update) {
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), scope)
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, options, dryrun.IsDryRun(options.DryRun), userInfo), scope)
|
||||
}
|
||||
}
|
||||
return newObj, nil
|
||||
@@ -172,11 +173,11 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa
|
||||
rest.DefaultUpdatedObjectInfo(obj, transformers...),
|
||||
withAuthorization(rest.AdmissionToValidateObjectFunc(
|
||||
admit,
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), scope),
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, updateToCreateOptions(options), dryrun.IsDryRun(options.DryRun), userInfo), scope),
|
||||
scope.Authorizer, createAuthorizerAttributes),
|
||||
rest.AdmissionToValidateObjectUpdateFunc(
|
||||
admit,
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), scope),
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, options, dryrun.IsDryRun(options.DryRun), userInfo), scope),
|
||||
false,
|
||||
options,
|
||||
)
|
||||
@@ -229,3 +230,16 @@ func withAuthorization(validate rest.ValidateObjectFunc, a authorizer.Authorizer
|
||||
return errors.NewForbidden(gr, name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// updateToCreateOptions creates a CreateOptions with the same field values as the provided UpdateOptions.
|
||||
func updateToCreateOptions(uo *metav1.UpdateOptions) *metav1.CreateOptions {
|
||||
if uo == nil {
|
||||
return nil
|
||||
}
|
||||
co := &metav1.CreateOptions{
|
||||
DryRun: uo.DryRun,
|
||||
FieldManager: uo.FieldManager,
|
||||
}
|
||||
co.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("CreateOptions"))
|
||||
return co
|
||||
}
|
||||
|
@@ -175,6 +175,7 @@ func AdmissionToValidateObjectFunc(admit admission.Interface, staticAttributes a
|
||||
staticAttributes.GetResource(),
|
||||
staticAttributes.GetSubresource(),
|
||||
staticAttributes.GetOperation(),
|
||||
staticAttributes.GetOperationOptions(),
|
||||
staticAttributes.IsDryRun(),
|
||||
staticAttributes.GetUserInfo(),
|
||||
)
|
||||
|
@@ -271,6 +271,7 @@ func AdmissionToValidateObjectUpdateFunc(admit admission.Interface, staticAttrib
|
||||
staticAttributes.GetResource(),
|
||||
staticAttributes.GetSubresource(),
|
||||
staticAttributes.GetOperation(),
|
||||
staticAttributes.GetOperationOptions(),
|
||||
staticAttributes.IsDryRun(),
|
||||
staticAttributes.GetUserInfo(),
|
||||
)
|
||||
|
@@ -136,6 +136,7 @@ func TestBanflunderAdmissionPlugin(t *testing.T) {
|
||||
scenario.admissionInputResource,
|
||||
"",
|
||||
admission.Create,
|
||||
&metav1.CreateOptions{},
|
||||
false,
|
||||
nil),
|
||||
nil,
|
||||
|
@@ -154,9 +154,11 @@ type holder struct {
|
||||
recordNamespace string
|
||||
recordName string
|
||||
|
||||
expectGVK schema.GroupVersionKind
|
||||
expectObject bool
|
||||
expectOldObject bool
|
||||
expectGVK schema.GroupVersionKind
|
||||
expectObject bool
|
||||
expectOldObject bool
|
||||
expectOptionsGVK schema.GroupVersionKind
|
||||
expectOptions bool
|
||||
|
||||
recorded map[string]*v1beta1.AdmissionRequest
|
||||
}
|
||||
@@ -172,12 +174,14 @@ func (h *holder) reset(t *testing.T) {
|
||||
h.recordNamespace = ""
|
||||
h.expectObject = false
|
||||
h.expectOldObject = false
|
||||
h.expectOptionsGVK = schema.GroupVersionKind{}
|
||||
h.expectOptions = false
|
||||
h.recorded = map[string]*v1beta1.AdmissionRequest{
|
||||
mutation: 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
|
||||
if len(namespace) == 0 && gvk.Group == "" && gvk.Version == "v1" && gvk.Kind == "Namespace" && operation != v1beta1.Create {
|
||||
namespace = name
|
||||
@@ -192,6 +196,8 @@ func (h *holder) expect(gvr schema.GroupVersionResource, gvk schema.GroupVersion
|
||||
h.recordNamespace = namespace
|
||||
h.expectObject = object
|
||||
h.expectOldObject = oldObject
|
||||
h.expectOptionsGVK = optionsGVK
|
||||
h.expectOptions = options
|
||||
h.recorded = map[string]*v1beta1.AdmissionRequest{
|
||||
mutation: nil,
|
||||
validation: nil,
|
||||
@@ -286,6 +292,14 @@ func (h *holder) verifyRequest(request *v1beta1.AdmissionRequest) error {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -299,6 +313,16 @@ func (h *holder) verifyObject(obj runtime.Object) error {
|
||||
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.
|
||||
func TestWebhookV1beta1(t *testing.T) {
|
||||
// holder communicates expectations to webhooks, and results from webhooks
|
||||
@@ -457,7 +481,7 @@ func testResourceCreate(c *testContext) {
|
||||
if c.resource.Namespaced {
|
||||
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{})
|
||||
if err != nil {
|
||||
c.t.Error(err)
|
||||
@@ -472,7 +496,7 @@ func testResourceUpdate(c *testContext) {
|
||||
return err
|
||||
}
|
||||
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{})
|
||||
return err
|
||||
}); err != nil {
|
||||
@@ -487,7 +511,7 @@ func testResourcePatch(c *testContext) {
|
||||
c.t.Error(err)
|
||||
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(
|
||||
obj.GetName(),
|
||||
types.MergePatchType,
|
||||
@@ -507,7 +531,7 @@ func testResourceDelete(c *testContext) {
|
||||
}
|
||||
background := metav1.DeletePropagationBackground
|
||||
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})
|
||||
if err != nil {
|
||||
c.t.Error(err)
|
||||
@@ -553,7 +577,7 @@ func testResourceDeletecollection(c *testContext) {
|
||||
}
|
||||
|
||||
// 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
|
||||
err = c.client.Resource(c.gvr).Namespace(obj.GetNamespace()).DeleteCollection(&metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background}, metav1.ListOptions{LabelSelector: "webhooktest=true"})
|
||||
@@ -618,7 +642,7 @@ func testSubresourceUpdate(c *testContext) {
|
||||
submitObj.SetAnnotations(map[string]string{"subresourceupdate": "true"})
|
||||
|
||||
// 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(
|
||||
submitObj,
|
||||
@@ -645,7 +669,7 @@ func testSubresourcePatch(c *testContext) {
|
||||
subresources := strings.Split(c.gvr.Resource, "/")[1:]
|
||||
|
||||
// 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(
|
||||
obj.GetName(),
|
||||
@@ -681,7 +705,7 @@ func testNamespaceDelete(c *testContext) {
|
||||
background := metav1.DeletePropagationBackground
|
||||
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})
|
||||
if err != nil {
|
||||
c.t.Error(err)
|
||||
@@ -707,7 +731,7 @@ func testNamespaceDelete(c *testContext) {
|
||||
}
|
||||
|
||||
// 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})
|
||||
if err != nil {
|
||||
c.t.Error(err)
|
||||
@@ -737,7 +761,7 @@ func testDeploymentRollback(c *testContext) {
|
||||
gvrWithoutSubresources.Resource = strings.Split(gvrWithoutSubresources.Resource, "/")[0]
|
||||
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
|
||||
switch c.gvr {
|
||||
@@ -786,7 +810,7 @@ func testPodConnectSubresource(c *testContext) {
|
||||
for _, httpMethod := range []string{"GET", "POST"} {
|
||||
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
|
||||
switch c.gvr {
|
||||
case gvr("", "v1", "pods/exec"):
|
||||
@@ -828,7 +852,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 {
|
||||
case gvr("", "v1", "bindings"):
|
||||
@@ -896,7 +920,7 @@ func testSubresourceProxy(c *testContext) {
|
||||
}
|
||||
|
||||
// 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
|
||||
err = request.Resource(gvrWithoutSubresources.Resource).Name(obj.GetName()).SubResource(subresources...).Do().Error()
|
||||
if err != nil {
|
||||
@@ -919,6 +943,7 @@ func newWebhookHandler(t *testing.T, holder *holder, phase string) http.Handler
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if contentType := r.Header.Get("Content-Type"); contentType != "application/json" {
|
||||
t.Errorf("contentType=%s, expect application/json", contentType)
|
||||
return
|
||||
@@ -956,6 +981,16 @@ func newWebhookHandler(t *testing.T, holder *holder, phase string) http.Handler
|
||||
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 {
|
||||
// only record requests originating from this integration test's client
|
||||
holder.record(phase, review.Request)
|
||||
@@ -1044,6 +1079,12 @@ func gvk(group, version, kind string) schema.GroupVersionKind {
|
||||
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 {
|
||||
if !sets.NewString(resource.Verbs...).HasAny("create", "update", "patch", "connect", "delete", "deletecollection") {
|
||||
return false
|
||||
|
Reference in New Issue
Block a user