mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Merge pull request #66391 from jennybuckley/dry-run-admission
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Support dry run in admission plugins **What this PR does / why we need it**: Adds support for dry run to admission controllers as outlined by https://github.com/kubernetes/community/pull/2387 - [x] add IsDryRun() to admission.Attributes interface - [x] add dry run support to NamespaceAutoProvision - [x] add dry run support to ResourceQuota - [x] add dry run support to EventRateLimit The following is being done in a follow up PR: - [x] add DryRun to ```admission.k8s.io/v1beta1.AdmissionReview``` - [x] add DryRunnable to ```admissionregistration.k8s.io/v1beta1.(Valid|Mut)atingWebhookConfiguration``` - [x] add dry run support to (Valid|Mut)atingAdmissionWebhook /sig api-machinery **Release note**: ```release-note In clusters where the DryRun feature is enabled, dry-run requests will go through the normal admission chain. Because of this, ImagePolicyWebhook authors should especially make sure that their webhooks do not rely on side effects. ``` Here is a list of the admission controllers that were considered when making this PR: - AlwaysAdmit: No side effects - AlwaysPullImages: No side effects - LimitPodHardAntiAffinityTopology: No side effects - DefaultTolerationSeconds: No side effects - AlwaysDeny: No side effects - EventRateLimit: Has side possible effect of affecting the rate, skipping this entire plugin in dry-run case since it won't correspond to an actual write to etcd anyway - DenyEscalatingExec: No side effects - DenyExecOnPrivileged: Deprecated, and has no side effects - ExtendedResourceToleration: No side effects - OwnerReferencesPermissionEnforcement: No side effects - ImagePolicyWebhook: No side effects* (*this uses a webhook but it is very specialized. It only sees pod container images, for the purpose of accepting or rejecting certain image sources, so it is very unlikely that it would rely on side effects.) - LimitRanger: No side effects - NamespaceAutoProvision: Has possible side effect of creating a namespace, skipping the create in the dry-run case - NamespaceExists: No side effects - NodeRestriction: No side effects - PodNodeSelector: No side effects - PodPreset: No side effects - PodTolerationRestriction: No side effects - Priority: No side effects - ResourceQuota: Has side possible effect of taking up quota, will only check quota but skip changing quota in the dry-run case - PodSecurityPolicy: No side effects - SecurityContextDeny: No side effects - ServiceAccount: No side effects - PersistentVolumeLabel: No side effects - PersistentVolumeClaimResize: No side effects - DefaultStorageClass: No side effects - StorageObjectInUseProtection: No side effects - Initializers: No side effects - NamespaceLifecycle: No side effects - MutatingAdmissionWebhook: Same as below - ValidatingAdmissionWebhook: Has possible side effects depending on if webhook authors depend on side effects and a reconciliation mechanism. To fix this we will expose whether or not a request is dry-run to webhooks through AdmissionReview, and require that all called webhooks understand the field by checking if DryRunnable true is specified in the webhook config. This will be done in a separate PR because it requires an api-change
This commit is contained in:
commit
6fe7f9f4b7
@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
func TestAdmissionNonNilAttribute(t *testing.T) {
|
func TestAdmissionNonNilAttribute(t *testing.T) {
|
||||||
handler := NewAlwaysAdmit()
|
handler := NewAlwaysAdmit()
|
||||||
err := handler.(*alwaysAdmit).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler")
|
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, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler")
|
t.Errorf("Unexpected error returned from admission handler")
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func TestValidate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
expectedError := `pods "123" is forbidden: spec.initContainers[0].imagePullPolicy: Unsupported value: "": supported values: "Always"`
|
expectedError := `pods "123" is forbidden: spec.initContainers[0].imagePullPolicy: Unsupported value: "": supported values: "Always"`
|
||||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("missing expected error")
|
t.Fatal("missing expected error")
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ func TestOtherResources(t *testing.T) {
|
|||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
handler := &AlwaysPullImages{}
|
handler := &AlwaysPullImages{}
|
||||||
|
|
||||||
err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, 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, false, nil))
|
||||||
|
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -199,7 +199,7 @@ func TestInterPodAffinityAdmission(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
pod.Spec.Affinity = test.affinity
|
pod.Spec.Affinity = test.affinity
|
||||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||||
|
|
||||||
if test.errorExpected && err == nil {
|
if test.errorExpected && err == nil {
|
||||||
t.Errorf("Expected error for Anti Affinity %+v but did not get an error", test.affinity)
|
t.Errorf("Expected error for Anti Affinity %+v but did not get an error", test.affinity)
|
||||||
@ -267,7 +267,7 @@ func TestOtherResources(t *testing.T) {
|
|||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
handler := &Plugin{}
|
handler := &Plugin{}
|
||||||
|
|
||||||
err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, 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, false, nil))
|
||||||
|
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -395,7 +395,7 @@ func TestForgivenessAdmission(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
|
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
func TestAdmission(t *testing.T) {
|
func TestAdmission(t *testing.T) {
|
||||||
handler := NewAlwaysDeny()
|
handler := NewAlwaysDeny()
|
||||||
err := handler.(*alwaysDeny).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, nil))
|
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))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Expected error returned from admission handler")
|
t.Error("Expected error returned from admission handler")
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,13 @@ func (a *Plugin) Validate(attr admission.Attributes) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore all requests that specify dry-run
|
||||||
|
// because they don't correspond to any calls to etcd,
|
||||||
|
// they should not be affected by the ratelimit
|
||||||
|
if attr.IsDryRun() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var errors []error
|
var errors []error
|
||||||
// give each limit enforcer a chance to reject the event
|
// give each limit enforcer a chance to reject the event
|
||||||
for _, enforcer := range a.limitEnforcers {
|
for _, enforcer := range a.limitEnforcers {
|
||||||
|
@ -46,6 +46,7 @@ func attributesForRequest(rq request) admission.Attributes {
|
|||||||
api.Resource("resource").WithVersion("version"),
|
api.Resource("resource").WithVersion("version"),
|
||||||
"",
|
"",
|
||||||
admission.Create,
|
admission.Create,
|
||||||
|
rq.dryRun,
|
||||||
&user.DefaultInfo{Name: rq.username})
|
&user.DefaultInfo{Name: rq.username})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ type request struct {
|
|||||||
event *api.Event
|
event *api.Event
|
||||||
delay time.Duration
|
delay time.Duration
|
||||||
accepted bool
|
accepted bool
|
||||||
|
dryRun bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRequest(kind string) request {
|
func newRequest(kind string) request {
|
||||||
@ -91,6 +93,11 @@ func (r request) withEventComponent(component string) request {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r request) withDryRun(dryRun bool) request {
|
||||||
|
r.dryRun = dryRun
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func (r request) withUser(name string) request {
|
func (r request) withUser(name string) request {
|
||||||
r.username = name
|
r.username = name
|
||||||
return r
|
return r
|
||||||
@ -153,6 +160,21 @@ func TestEventRateLimiting(t *testing.T) {
|
|||||||
newEventRequest().blocked(),
|
newEventRequest().blocked(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "event not blocked by dry-run requests",
|
||||||
|
serverBurst: 3,
|
||||||
|
requests: []request{
|
||||||
|
newEventRequest(),
|
||||||
|
newEventRequest(),
|
||||||
|
newEventRequest().withDryRun(true),
|
||||||
|
newEventRequest().withDryRun(true),
|
||||||
|
newEventRequest().withDryRun(true),
|
||||||
|
newEventRequest().withDryRun(true),
|
||||||
|
newEventRequest(),
|
||||||
|
newEventRequest().blocked(),
|
||||||
|
newEventRequest().withDryRun(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "non-event not blocked after tokens exhausted",
|
name: "non-event not blocked after tokens exhausted",
|
||||||
serverBurst: 3,
|
serverBurst: 3,
|
||||||
|
@ -123,7 +123,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b
|
|||||||
// pods/exec
|
// pods/exec
|
||||||
{
|
{
|
||||||
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"}
|
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"}
|
||||||
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "exec", admission.Connect, nil))
|
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil))
|
||||||
if shouldAccept && err != nil {
|
if shouldAccept && err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b
|
|||||||
// pods/attach
|
// pods/attach
|
||||||
{
|
{
|
||||||
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"}
|
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"}
|
||||||
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "attach", admission.Connect, nil))
|
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil))
|
||||||
if shouldAccept && err != nil {
|
if shouldAccept && err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -354,7 +354,7 @@ func TestAdmit(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("[%d: %s] unexpected error %v for pod %+v", i, test.description, err, test.requestedPod)
|
t.Errorf("[%d: %s] unexpected error %v for pod %+v", i, test.description, err, test.requestedPod)
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ func TestGCAdmission(t *testing.T) {
|
|||||||
operation = admission.Update
|
operation = admission.Update
|
||||||
}
|
}
|
||||||
user := &user.DefaultInfo{Name: tc.username}
|
user := &user.DefaultInfo{Name: tc.username}
|
||||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, user)
|
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user)
|
||||||
|
|
||||||
err = gcAdmit.Validate(attributes)
|
err = gcAdmit.Validate(attributes)
|
||||||
if !tc.checkError(err) {
|
if !tc.checkError(err) {
|
||||||
@ -518,7 +518,7 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) {
|
|||||||
operation = admission.Update
|
operation = admission.Update
|
||||||
}
|
}
|
||||||
user := &user.DefaultInfo{Name: tc.username}
|
user := &user.DefaultInfo{Name: tc.username}
|
||||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, user)
|
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user)
|
||||||
|
|
||||||
err := gcAdmit.Validate(attributes)
|
err := gcAdmit.Validate(attributes)
|
||||||
if !tc.checkError(err) {
|
if !tc.checkError(err) {
|
||||||
|
@ -472,7 +472,7 @@ func TestTLSConfig(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
pod := goodPod(strconv.Itoa(rand.Intn(1000)))
|
pod := goodPod(strconv.Itoa(rand.Intn(1000)))
|
||||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
// Allow all and see if we get an error.
|
// Allow all and see if we get an error.
|
||||||
service.Allow()
|
service.Allow()
|
||||||
@ -561,7 +561,7 @@ func TestWebhookCache(t *testing.T) {
|
|||||||
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
|
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
attr := admission.NewAttributesRecord(goodPod("test"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
attr := admission.NewAttributesRecord(goodPod("test"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
serv.allow = true
|
serv.allow = true
|
||||||
|
|
||||||
@ -573,7 +573,7 @@ func TestWebhookCache(t *testing.T) {
|
|||||||
{statusCode: 200, expectedErr: false, expectedAuthorized: true, expectedCached: false},
|
{statusCode: 200, expectedErr: false, expectedAuthorized: true, expectedCached: false},
|
||||||
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
|
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
|
||||||
}
|
}
|
||||||
attr = admission.NewAttributesRecord(goodPod("test2"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
attr = admission.NewAttributesRecord(goodPod("test2"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
testWebhookCacheCases(t, serv, wh, attr, tests)
|
testWebhookCacheCases(t, serv, wh, attr, tests)
|
||||||
}
|
}
|
||||||
@ -747,7 +747,7 @@ func TestContainerCombinations(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
err = wh.Validate(attr)
|
err = wh.Validate(attr)
|
||||||
if tt.wantAllowed {
|
if tt.wantAllowed {
|
||||||
@ -825,7 +825,7 @@ func TestDefaultAllow(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
err = wh.Validate(attr)
|
err = wh.Validate(attr)
|
||||||
if tt.wantAllowed {
|
if tt.wantAllowed {
|
||||||
@ -917,7 +917,7 @@ func TestAnnotationFiltering(t *testing.T) {
|
|||||||
pod := goodPod("test")
|
pod := goodPod("test")
|
||||||
pod.Annotations = tt.annotations
|
pod.Annotations = tt.annotations
|
||||||
|
|
||||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
err = wh.Validate(attr)
|
err = wh.Validate(attr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -694,16 +694,16 @@ func TestLimitRangerIgnoresSubresource(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error since the pod did not specify resource limits in its update call")
|
t.Errorf("Expected an error since the pod did not specify resource limits in its update call")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
||||||
}
|
}
|
||||||
@ -720,16 +720,16 @@ func TestLimitRangerAdmitPod(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error since the pod did not specify resource limits in its update call")
|
t.Errorf("Expected an error since the pod did not specify resource limits in its update call")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
||||||
}
|
}
|
||||||
@ -738,7 +738,7 @@ func TestLimitRangerAdmitPod(t *testing.T) {
|
|||||||
terminatingPod := validPod("terminatingPod", 1, api.ResourceRequirements{})
|
terminatingPod := validPod("terminatingPod", 1, api.ResourceRequirements{})
|
||||||
now := metav1.Now()
|
now := metav1.Now()
|
||||||
terminatingPod.DeletionTimestamp = &now
|
terminatingPod.DeletionTimestamp = &now
|
||||||
err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("LimitRange should ignore a pod marked for termination")
|
t.Errorf("LimitRange should ignore a pod marked for termination")
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,11 @@ var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&Provision{})
|
|||||||
|
|
||||||
// Admit makes an admission decision based on the request attributes
|
// Admit makes an admission decision based on the request attributes
|
||||||
func (p *Provision) Admit(a admission.Attributes) error {
|
func (p *Provision) Admit(a admission.Attributes) error {
|
||||||
|
// Don't create a namespace if the request is for a dry-run.
|
||||||
|
if a.IsDryRun() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// if we're here, then we've already passed authentication, so we're allowed to do what we're trying to do
|
// if we're here, then we've already passed authentication, so we're allowed to do what we're trying to do
|
||||||
// if we're here, then the API server has found a route, which means that if we have a non-empty namespace
|
// if we're here, then the API server has found a route, which means that if we have a non-empty namespace
|
||||||
// its a namespaced resource.
|
// its a namespaced resource.
|
||||||
|
@ -98,7 +98,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error returned from admission handler")
|
t.Errorf("unexpected error returned from admission handler")
|
||||||
}
|
}
|
||||||
@ -118,7 +118,27 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error returned from admission handler")
|
||||||
|
}
|
||||||
|
if hasCreateNamespaceAction(mockClient) {
|
||||||
|
t.Errorf("unexpected create namespace action")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAdmissionDryRun verifies that no client call is made on a dry run request
|
||||||
|
func TestAdmissionDryRun(t *testing.T) {
|
||||||
|
namespace := "test"
|
||||||
|
mockClient := newMockClientForTest([]string{})
|
||||||
|
handler, informerFactory, err := newHandlerForTest(mockClient)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error initializing handler: %v", err)
|
||||||
|
}
|
||||||
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error returned from admission handler")
|
t.Errorf("unexpected error returned from admission handler")
|
||||||
}
|
}
|
||||||
@ -139,7 +159,7 @@ func TestIgnoreAdmission(t *testing.T) {
|
|||||||
chainHandler := admission.NewChainHandler(handler)
|
chainHandler := admission.NewChainHandler(handler)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = chainHandler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error returned from admission handler")
|
t.Errorf("unexpected error returned from admission handler")
|
||||||
}
|
}
|
||||||
@ -161,7 +181,7 @@ func TestAdmissionWithLatentCache(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error returned from admission handler")
|
t.Errorf("unexpected error returned from admission handler")
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error returned from admission handler")
|
t.Errorf("unexpected error returned from admission handler")
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
actions := ""
|
actions := ""
|
||||||
for _, action := range mockClient.Actions() {
|
for _, action := range mockClient.Actions() {
|
||||||
|
@ -175,61 +175,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "allow creating a mirror pod bound to self",
|
name: "allow creating a mirror pod bound to self",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mymirrorpod, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mymirrorpod, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of mirror pod bound to self",
|
name: "forbid update of mirror pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mymirrorpod, mymirrorpod, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mymirrorpod, mymirrorpod, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow delete of mirror pod bound to self",
|
name: "allow delete of mirror pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "", admission.Delete, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of mirror pod status bound to self",
|
name: "forbid create of mirror pod status bound to self",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mymirrorpod, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "status", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mymirrorpod, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "status", admission.Create, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of mirror pod status bound to self",
|
name: "allow update of mirror pod status bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mymirrorpod, mymirrorpod, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mymirrorpod, mymirrorpod, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "status", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of mirror pod status bound to self",
|
name: "forbid delete of mirror pod status bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "status", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "status", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow create of eviction for mirror pod bound to self",
|
name: "allow create of eviction for mirror pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for mirror pod bound to self",
|
name: "forbid update of eviction for mirror pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for mirror pod bound to self",
|
name: "forbid delete of eviction for mirror pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(mymirrorpodEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow create of unnamed eviction for mirror pod bound to self",
|
name: "allow create of unnamed eviction for mirror pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, mymirrorpod.Namespace, mymirrorpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -237,61 +237,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid creating a mirror pod bound to another",
|
name: "forbid creating a mirror pod bound to another",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(othermirrorpod, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(othermirrorpod, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of mirror pod bound to another",
|
name: "forbid update of mirror pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(othermirrorpod, othermirrorpod, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(othermirrorpod, othermirrorpod, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of mirror pod bound to another",
|
name: "forbid delete of mirror pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "", admission.Delete, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of mirror pod status bound to another",
|
name: "forbid create of mirror pod status bound to another",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(othermirrorpod, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "status", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(othermirrorpod, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "status", admission.Create, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of mirror pod status bound to another",
|
name: "forbid update of mirror pod status bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(othermirrorpod, othermirrorpod, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(othermirrorpod, othermirrorpod, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "status", admission.Update, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of mirror pod status bound to another",
|
name: "forbid delete of mirror pod status bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "status", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "status", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of eviction for mirror pod bound to another",
|
name: "forbid create of eviction for mirror pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for mirror pod bound to another",
|
name: "forbid update of eviction for mirror pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for mirror pod bound to another",
|
name: "forbid delete of eviction for mirror pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(othermirrorpodEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of unnamed eviction for mirror pod to another",
|
name: "forbid create of unnamed eviction for mirror pod to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, othermirrorpod.Namespace, othermirrorpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -299,61 +299,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid creating a mirror pod unbound",
|
name: "forbid creating a mirror pod unbound",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundmirrorpod, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unboundmirrorpod, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of mirror pod unbound",
|
name: "forbid update of mirror pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundmirrorpod, unboundmirrorpod, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(unboundmirrorpod, unboundmirrorpod, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of mirror pod unbound",
|
name: "forbid delete of mirror pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "", admission.Delete, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of mirror pod status unbound",
|
name: "forbid create of mirror pod status unbound",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundmirrorpod, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "status", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unboundmirrorpod, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "status", admission.Create, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of mirror pod status unbound",
|
name: "forbid update of mirror pod status unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundmirrorpod, unboundmirrorpod, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(unboundmirrorpod, unboundmirrorpod, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "status", admission.Update, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of mirror pod status unbound",
|
name: "forbid delete of mirror pod status unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "status", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "status", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of eviction for mirror pod unbound",
|
name: "forbid create of eviction for mirror pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for mirror pod unbound",
|
name: "forbid update of eviction for mirror pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for mirror pod unbound",
|
name: "forbid delete of eviction for mirror pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(unboundmirrorpodEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of unnamed eviction for mirror pod unbound",
|
name: "forbid create of unnamed eviction for mirror pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, unboundmirrorpod.Namespace, unboundmirrorpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -361,55 +361,55 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid creating a normal pod bound to self",
|
name: "forbid creating a normal pod bound to self",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypod, nil, podKind, mypod.Namespace, mypod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mypod, nil, podKind, mypod.Namespace, mypod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "can only create mirror pods",
|
err: "can only create mirror pods",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of normal pod bound to self",
|
name: "forbid update of normal pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypod, mypod, podKind, mypod.Namespace, mypod.Name, podResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mypod, mypod, podKind, mypod.Namespace, mypod.Name, podResource, "", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow delete of normal pod bound to self",
|
name: "allow delete of normal pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, mypod.Namespace, mypod.Name, podResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, mypod.Namespace, mypod.Name, podResource, "", admission.Delete, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of normal pod status bound to self",
|
name: "forbid create of normal pod status bound to self",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypod, nil, podKind, mypod.Namespace, mypod.Name, podResource, "status", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mypod, nil, podKind, mypod.Namespace, mypod.Name, podResource, "status", admission.Create, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of normal pod status bound to self",
|
name: "allow update of normal pod status bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypod, mypod, podKind, mypod.Namespace, mypod.Name, podResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mypod, mypod, podKind, mypod.Namespace, mypod.Name, podResource, "status", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of normal pod status bound to self",
|
name: "forbid delete of normal pod status bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, mypod.Namespace, mypod.Name, podResource, "status", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, mypod.Namespace, mypod.Name, podResource, "status", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for normal pod bound to self",
|
name: "forbid update of eviction for normal pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for normal pod bound to self",
|
name: "forbid delete of eviction for normal pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow create of unnamed eviction for normal pod bound to self",
|
name: "allow create of unnamed eviction for normal pod bound to self",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -417,61 +417,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid creating a normal pod bound to another",
|
name: "forbid creating a normal pod bound to another",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(otherpod, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(otherpod, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "can only create mirror pods",
|
err: "can only create mirror pods",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of normal pod bound to another",
|
name: "forbid update of normal pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(otherpod, otherpod, podKind, otherpod.Namespace, otherpod.Name, podResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(otherpod, otherpod, podKind, otherpod.Namespace, otherpod.Name, podResource, "", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of normal pod bound to another",
|
name: "forbid delete of normal pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "", admission.Delete, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of normal pod status bound to another",
|
name: "forbid create of normal pod status bound to another",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(otherpod, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "status", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(otherpod, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "status", admission.Create, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of normal pod status bound to another",
|
name: "forbid update of normal pod status bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(otherpod, otherpod, podKind, otherpod.Namespace, otherpod.Name, podResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(otherpod, otherpod, podKind, otherpod.Namespace, otherpod.Name, podResource, "status", admission.Update, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of normal pod status bound to another",
|
name: "forbid delete of normal pod status bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "status", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, otherpod.Namespace, otherpod.Name, podResource, "status", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of eviction for normal pod bound to another",
|
name: "forbid create of eviction for normal pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for normal pod bound to another",
|
name: "forbid update of eviction for normal pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for normal pod bound to another",
|
name: "forbid delete of eviction for normal pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(otherpodEviction, nil, evictionKind, otherpodEviction.Namespace, otherpodEviction.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of unnamed eviction for normal pod bound to another",
|
name: "forbid create of unnamed eviction for normal pod bound to another",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, otherpod.Namespace, otherpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, otherpod.Namespace, otherpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -479,61 +479,61 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid creating a normal pod unbound",
|
name: "forbid creating a normal pod unbound",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "can only create mirror pods",
|
err: "can only create mirror pods",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of normal pod unbound",
|
name: "forbid update of normal pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of normal pod unbound",
|
name: "forbid delete of normal pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Delete, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of normal pod status unbound",
|
name: "forbid create of normal pod status unbound",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Create, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of normal pod status unbound",
|
name: "forbid update of normal pod status unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Update, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of normal pod status unbound",
|
name: "forbid delete of normal pod status unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of eviction for normal pod unbound",
|
name: "forbid create of eviction for normal pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for normal pod unbound",
|
name: "forbid update of eviction for normal pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for normal pod unbound",
|
name: "forbid delete of eviction for normal pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(unboundpodEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of unnamed eviction for normal unbound",
|
name: "forbid create of unnamed eviction for normal unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, unboundpod.Namespace, unboundpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "spec.nodeName set to itself",
|
err: "spec.nodeName set to itself",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -541,31 +541,31 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid delete of unknown pod",
|
name: "forbid delete of unknown pod",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Delete, false, mynode),
|
||||||
err: "not found",
|
err: "not found",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of eviction for unknown pod",
|
name: "forbid create of eviction for unknown pod",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "not found",
|
err: "not found",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for unknown pod",
|
name: "forbid update of eviction for unknown pod",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for unknown pod",
|
name: "forbid delete of eviction for unknown pod",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of unnamed eviction for unknown pod",
|
name: "forbid create of unnamed eviction for unknown pod",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, mypod.Namespace, mypod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "not found",
|
err: "not found",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -573,26 +573,26 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "allow create of eviction for unnamed pod",
|
name: "allow create of eviction for unnamed pod",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
// use the submitted eviction resource name as the pod name
|
// use the submitted eviction resource name as the pod name
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of eviction for unnamed pod",
|
name: "forbid update of eviction for unnamed pod",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Update, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of eviction for unnamed pod",
|
name: "forbid delete of eviction for unnamed pod",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(mypodEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Delete, false, mynode),
|
||||||
err: "forbidden: unexpected operation",
|
err: "forbidden: unexpected operation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of unnamed eviction for unnamed pod",
|
name: "forbid create of unnamed eviction for unnamed pod",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, unnamedpod.Namespace, unnamedpod.Name, podResource, "eviction", admission.Create, false, mynode),
|
||||||
err: "could not determine pod from request data",
|
err: "could not determine pod from request data",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -600,25 +600,25 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid create of pod referencing service account",
|
name: "forbid create of pod referencing service account",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(sapod, nil, podKind, sapod.Namespace, sapod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(sapod, nil, podKind, sapod.Namespace, sapod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "reference a service account",
|
err: "reference a service account",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of pod referencing secret",
|
name: "forbid create of pod referencing secret",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(secretpod, nil, podKind, secretpod.Namespace, secretpod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(secretpod, nil, podKind, secretpod.Namespace, secretpod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "reference secrets",
|
err: "reference secrets",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of pod referencing configmap",
|
name: "forbid create of pod referencing configmap",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(configmappod, nil, podKind, configmappod.Namespace, configmappod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(configmappod, nil, podKind, configmappod.Namespace, configmappod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "reference configmaps",
|
err: "reference configmaps",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of pod referencing persistentvolumeclaim",
|
name: "forbid create of pod referencing persistentvolumeclaim",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, false, mynode),
|
||||||
err: "reference persistentvolumeclaims",
|
err: "reference persistentvolumeclaims",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -626,91 +626,91 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "allow create of my node",
|
name: "allow create of my node",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow create of my node pulling name from object",
|
name: "allow create of my node pulling name from object",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObj, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow create of my node with taints",
|
name: "allow create of my node with taints",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjTaintA, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjTaintA, nil, nodeKind, mynodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of my node",
|
name: "allow update of my node",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow delete of my node",
|
name: "allow delete of my node",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Delete, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of my node status",
|
name: "allow update of my node status",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "status", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of my node with non-nil configSource",
|
name: "forbid create of my node with non-nil configSource",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjConfigA, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjConfigA, nil, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Create, false, mynode),
|
||||||
err: "create with non-nil configSource",
|
err: "create with non-nil configSource",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of my node: nil configSource to new non-nil configSource",
|
name: "forbid update of my node: nil configSource to new non-nil configSource",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "update configSource to a new non-nil configSource",
|
err: "update configSource to a new non-nil configSource",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of my node: non-nil configSource to new non-nil configSource",
|
name: "forbid update of my node: non-nil configSource to new non-nil configSource",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjConfigB, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjConfigB, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "update configSource to a new non-nil configSource",
|
err: "update configSource to a new non-nil configSource",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of my node: non-nil configSource unchanged",
|
name: "allow update of my node: non-nil configSource unchanged",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjConfigA, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of my node: non-nil configSource to nil configSource",
|
name: "allow update of my node: non-nil configSource to nil configSource",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjConfigA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of my node: no change to taints",
|
name: "allow update of my node: no change to taints",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of my node: add taints",
|
name: "forbid update of my node: add taints",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "cannot modify taints",
|
err: "cannot modify taints",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of my node: remove taints",
|
name: "forbid update of my node: remove taints",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjTaintA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "cannot modify taints",
|
err: "cannot modify taints",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of my node: change taints",
|
name: "forbid update of my node: change taints",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintB, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(mynodeObjTaintA, mynodeObjTaintB, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "cannot modify taints",
|
err: "cannot modify taints",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -718,31 +718,31 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "forbid create of other node",
|
name: "forbid create of other node",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Create, false, mynode),
|
||||||
err: "cannot modify node",
|
err: "cannot modify node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of other node pulling name from object",
|
name: "forbid create of other node pulling name from object",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, "", nodeResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(othernodeObj, nil, nodeKind, othernodeObj.Namespace, "", nodeResource, "", admission.Create, false, mynode),
|
||||||
err: "cannot modify node",
|
err: "cannot modify node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of other node",
|
name: "forbid update of other node",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Update, false, mynode),
|
||||||
err: "cannot modify node",
|
err: "cannot modify node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid delete of other node",
|
name: "forbid delete of other node",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "", admission.Delete, false, mynode),
|
||||||
err: "cannot modify node",
|
err: "cannot modify node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid update of other node status",
|
name: "forbid update of other node status",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "status", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(othernodeObj, othernodeObj, nodeKind, othernodeObj.Namespace, othernodeObj.Name, nodeResource, "status", admission.Update, false, mynode),
|
||||||
err: "cannot modify node",
|
err: "cannot modify node",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -751,54 +751,54 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
name: "forbid create of unbound token",
|
name: "forbid create of unbound token",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
features: trEnabledFeature,
|
features: trEnabledFeature,
|
||||||
attributes: admission.NewAttributesRecord(makeTokenRequest("", ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(makeTokenRequest("", ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, false, mynode),
|
||||||
err: "not bound to a pod",
|
err: "not bound to a pod",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of token bound to nonexistant pod",
|
name: "forbid create of token bound to nonexistant pod",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
features: trEnabledFeature,
|
features: trEnabledFeature,
|
||||||
attributes: admission.NewAttributesRecord(makeTokenRequest("nopod", "someuid"), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(makeTokenRequest("nopod", "someuid"), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, false, mynode),
|
||||||
err: "not found",
|
err: "not found",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of token bound to pod without uid",
|
name: "forbid create of token bound to pod without uid",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
features: trEnabledFeature,
|
features: trEnabledFeature,
|
||||||
attributes: admission.NewAttributesRecord(makeTokenRequest(mypod.Name, ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(makeTokenRequest(mypod.Name, ""), nil, tokenrequestKind, "ns", "mysa", svcacctResource, "token", admission.Create, false, mynode),
|
||||||
err: "pod binding without a uid",
|
err: "pod binding without a uid",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forbid create of token bound to pod scheduled on another node",
|
name: "forbid create of token bound to pod scheduled on another node",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
features: trEnabledFeature,
|
features: trEnabledFeature,
|
||||||
attributes: admission.NewAttributesRecord(makeTokenRequest(otherpod.Name, otherpod.UID), nil, tokenrequestKind, otherpod.Namespace, "mysa", svcacctResource, "token", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(makeTokenRequest(otherpod.Name, otherpod.UID), nil, tokenrequestKind, otherpod.Namespace, "mysa", svcacctResource, "token", admission.Create, false, mynode),
|
||||||
err: "pod scheduled on a different node",
|
err: "pod scheduled on a different node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow create of token bound to pod scheduled this node",
|
name: "allow create of token bound to pod scheduled this node",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
features: trEnabledFeature,
|
features: trEnabledFeature,
|
||||||
attributes: admission.NewAttributesRecord(makeTokenRequest(mypod.Name, mypod.UID), nil, tokenrequestKind, mypod.Namespace, "mysa", svcacctResource, "token", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(makeTokenRequest(mypod.Name, mypod.UID), nil, tokenrequestKind, mypod.Namespace, "mysa", svcacctResource, "token", admission.Create, false, mynode),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Unrelated objects
|
// Unrelated objects
|
||||||
{
|
{
|
||||||
name: "allow create of unrelated object",
|
name: "allow create of unrelated object",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(&api.ConfigMap{}, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Create, mynode),
|
attributes: admission.NewAttributesRecord(&api.ConfigMap{}, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Create, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow update of unrelated object",
|
name: "allow update of unrelated object",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(&api.ConfigMap{}, &api.ConfigMap{}, configmapKind, "myns", "mycm", configmapResource, "", admission.Update, mynode),
|
attributes: admission.NewAttributesRecord(&api.ConfigMap{}, &api.ConfigMap{}, configmapKind, "myns", "mycm", configmapResource, "", admission.Update, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow delete of unrelated object",
|
name: "allow delete of unrelated object",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Delete, mynode),
|
attributes: admission.NewAttributesRecord(nil, nil, configmapKind, "myns", "mycm", configmapResource, "", admission.Delete, false, mynode),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -806,37 +806,37 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "allow unrelated user creating a normal pod unbound",
|
name: "allow unrelated user creating a normal pod unbound",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Create, bob),
|
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Create, false, bob),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow unrelated user update of normal pod unbound",
|
name: "allow unrelated user update of normal pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Update, bob),
|
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Update, false, bob),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow unrelated user delete of normal pod unbound",
|
name: "allow unrelated user delete of normal pod unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Delete, bob),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "", admission.Delete, false, bob),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow unrelated user create of normal pod status unbound",
|
name: "allow unrelated user create of normal pod status unbound",
|
||||||
podsGetter: noExistingPods,
|
podsGetter: noExistingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Create, bob),
|
attributes: admission.NewAttributesRecord(unboundpod, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Create, false, bob),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow unrelated user update of normal pod status unbound",
|
name: "allow unrelated user update of normal pod status unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Update, bob),
|
attributes: admission.NewAttributesRecord(unboundpod, unboundpod, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Update, false, bob),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allow unrelated user delete of normal pod status unbound",
|
name: "allow unrelated user delete of normal pod status unbound",
|
||||||
podsGetter: existingPods,
|
podsGetter: existingPods,
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Delete, bob),
|
attributes: admission.NewAttributesRecord(nil, nil, podKind, unboundpod.Namespace, unboundpod.Name, podResource, "status", admission.Delete, false, bob),
|
||||||
err: "",
|
err: "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ func TestPodAdmission(t *testing.T) {
|
|||||||
handler.clusterNodeSelectors[namespace.Name] = test.whitelist
|
handler.clusterNodeSelectors[namespace.Name] = test.whitelist
|
||||||
pod.Spec = api.PodSpec{NodeSelector: test.podNodeSelector}
|
pod.Spec = api.PodSpec{NodeSelector: test.podNodeSelector}
|
||||||
|
|
||||||
err := handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if test.admit && err != nil {
|
if test.admit && err != nil {
|
||||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||||
} else if !test.admit && err == nil {
|
} else if !test.admit && err == nil {
|
||||||
@ -175,7 +175,7 @@ func TestPodAdmission(t *testing.T) {
|
|||||||
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
|
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
|
||||||
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
|
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
|
||||||
}
|
}
|
||||||
err = handler.Validate(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if test.admit && err != nil {
|
if test.admit && err != nil {
|
||||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||||
} else if !test.admit && err == nil {
|
} else if !test.admit && err == nil {
|
||||||
@ -183,7 +183,7 @@ func TestPodAdmission(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handles update of uninitialized pod like it's newly created.
|
// handles update of uninitialized pod like it's newly created.
|
||||||
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if test.admit && err != nil {
|
if test.admit && err != nil {
|
||||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||||
} else if !test.admit && err == nil {
|
} else if !test.admit && err == nil {
|
||||||
@ -192,7 +192,7 @@ func TestPodAdmission(t *testing.T) {
|
|||||||
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
|
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
|
||||||
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
|
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
|
||||||
}
|
}
|
||||||
err = handler.Validate(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Validate(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if test.admit && err != nil {
|
if test.admit && err != nil {
|
||||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||||
} else if !test.admit && err == nil {
|
} else if !test.admit && err == nil {
|
||||||
@ -243,7 +243,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the update of initialized pod is not ignored, an error will be returned because the pod's nodeSelector conflicts with namespace's nodeSelector.
|
// if the update of initialized pod is not ignored, an error will be returned because the pod's nodeSelector conflicts with namespace's nodeSelector.
|
||||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected no error, got: %v", err)
|
t.Errorf("expected no error, got: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -818,6 +818,7 @@ func admitPod(pod *api.Pod, pip *settings.PodPreset) error {
|
|||||||
api.Resource("pods").WithVersion("version"),
|
api.Resource("pods").WithVersion("version"),
|
||||||
"",
|
"",
|
||||||
kadmission.Create,
|
kadmission.Create,
|
||||||
|
false,
|
||||||
&user.DefaultInfo{},
|
&user.DefaultInfo{},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ func TestPodAdmission(t *testing.T) {
|
|||||||
oldPod.Initializers = &metav1.Initializers{Pending: []metav1.Initializer{{Name: "init"}}}
|
oldPod.Initializers = &metav1.Initializers{Pending: []metav1.Initializer{{Name: "init"}}}
|
||||||
oldPod.Spec.Tolerations = []api.Toleration{{Key: "testKey", Operator: "Equal", Value: "testValue1", Effect: "NoSchedule", TolerationSeconds: nil}}
|
oldPod.Spec.Tolerations = []api.Toleration{{Key: "testKey", Operator: "Equal", Value: "testValue1", Effect: "NoSchedule", TolerationSeconds: nil}}
|
||||||
|
|
||||||
err = handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
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))
|
||||||
if test.admit && err != nil {
|
if test.admit && err != nil {
|
||||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||||
} else if !test.admit && err == nil {
|
} else if !test.admit && err == nil {
|
||||||
@ -271,7 +271,7 @@ func TestPodAdmission(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handles update of uninitialized pod like it's newly created.
|
// handles update of uninitialized pod like it's newly created.
|
||||||
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if test.admit && err != nil {
|
if test.admit && err != nil {
|
||||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||||
} else if !test.admit && err == nil {
|
} else if !test.admit && err == nil {
|
||||||
@ -348,7 +348,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the update of initialized pod is not ignored, an error will be returned because the pod's Tolerations conflicts with namespace's Tolerations.
|
// if the update of initialized pod is not ignored, an error will be returned because the pod's Tolerations conflicts with namespace's Tolerations.
|
||||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", pod.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected no error, got: %v", err)
|
t.Errorf("expected no error, got: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,7 @@ func TestPriorityClassAdmission(t *testing.T) {
|
|||||||
scheduling.Resource("priorityclasses").WithVersion("version"),
|
scheduling.Resource("priorityclasses").WithVersion("version"),
|
||||||
"",
|
"",
|
||||||
admission.Create,
|
admission.Create,
|
||||||
|
false,
|
||||||
test.userInfo,
|
test.userInfo,
|
||||||
)
|
)
|
||||||
err := ctrl.Validate(attrs)
|
err := ctrl.Validate(attrs)
|
||||||
@ -186,7 +187,7 @@ func TestDefaultPriority(t *testing.T) {
|
|||||||
name: "add a default class",
|
name: "add a default class",
|
||||||
classesBefore: []*scheduling.PriorityClass{nondefaultClass1},
|
classesBefore: []*scheduling.PriorityClass{nondefaultClass1},
|
||||||
classesAfter: []*scheduling.PriorityClass{nondefaultClass1, defaultClass1},
|
classesAfter: []*scheduling.PriorityClass{nondefaultClass1, defaultClass1},
|
||||||
attributes: admission.NewAttributesRecord(defaultClass1, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Create, nil),
|
attributes: admission.NewAttributesRecord(defaultClass1, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Create, false, nil),
|
||||||
expectedDefaultBefore: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
expectedDefaultBefore: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||||
expectedDefaultAfter: defaultClass1.Value,
|
expectedDefaultAfter: defaultClass1.Value,
|
||||||
},
|
},
|
||||||
@ -194,7 +195,7 @@ func TestDefaultPriority(t *testing.T) {
|
|||||||
name: "multiple default classes resolves to the minimum value among them",
|
name: "multiple default classes resolves to the minimum value among them",
|
||||||
classesBefore: []*scheduling.PriorityClass{defaultClass1, defaultClass2},
|
classesBefore: []*scheduling.PriorityClass{defaultClass1, defaultClass2},
|
||||||
classesAfter: []*scheduling.PriorityClass{defaultClass2},
|
classesAfter: []*scheduling.PriorityClass{defaultClass2},
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, nil),
|
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, false, nil),
|
||||||
expectedDefaultBefore: defaultClass1.Value,
|
expectedDefaultBefore: defaultClass1.Value,
|
||||||
expectedDefaultAfter: defaultClass2.Value,
|
expectedDefaultAfter: defaultClass2.Value,
|
||||||
},
|
},
|
||||||
@ -202,7 +203,7 @@ func TestDefaultPriority(t *testing.T) {
|
|||||||
name: "delete default priority class",
|
name: "delete default priority class",
|
||||||
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
||||||
classesAfter: []*scheduling.PriorityClass{},
|
classesAfter: []*scheduling.PriorityClass{},
|
||||||
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, nil),
|
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, false, nil),
|
||||||
expectedDefaultBefore: defaultClass1.Value,
|
expectedDefaultBefore: defaultClass1.Value,
|
||||||
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||||
},
|
},
|
||||||
@ -210,7 +211,7 @@ func TestDefaultPriority(t *testing.T) {
|
|||||||
name: "update default class and remove its global default",
|
name: "update default class and remove its global default",
|
||||||
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
||||||
classesAfter: []*scheduling.PriorityClass{&updatedDefaultClass1},
|
classesAfter: []*scheduling.PriorityClass{&updatedDefaultClass1},
|
||||||
attributes: admission.NewAttributesRecord(&updatedDefaultClass1, defaultClass1, pcKind, "", defaultClass1.Name, pcResource, "", admission.Update, nil),
|
attributes: admission.NewAttributesRecord(&updatedDefaultClass1, defaultClass1, pcKind, "", defaultClass1.Name, pcResource, "", admission.Update, false, nil),
|
||||||
expectedDefaultBefore: defaultClass1.Value,
|
expectedDefaultBefore: defaultClass1.Value,
|
||||||
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||||
},
|
},
|
||||||
@ -568,6 +569,7 @@ func TestPodAdmission(t *testing.T) {
|
|||||||
api.Resource("pods").WithVersion("version"),
|
api.Resource("pods").WithVersion("version"),
|
||||||
"",
|
"",
|
||||||
admission.Create,
|
admission.Create,
|
||||||
|
false,
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
err := ctrl.Admit(attrs)
|
err := ctrl.Admit(attrs)
|
||||||
|
@ -150,7 +150,7 @@ func TestAdmissionIgnoresDelete(t *testing.T) {
|
|||||||
evaluator: evaluator,
|
evaluator: evaluator,
|
||||||
}
|
}
|
||||||
namespace := "default"
|
namespace := "default"
|
||||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", api.Resource("pods").WithVersion("version"), "", admission.Delete, nil))
|
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", api.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("ResourceQuota should admit all deletes: %v", err)
|
t.Errorf("ResourceQuota should admit all deletes: %v", err)
|
||||||
}
|
}
|
||||||
@ -187,11 +187,11 @@ func TestAdmissionIgnoresSubresources(t *testing.T) {
|
|||||||
}
|
}
|
||||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||||
newPod := validPod("123", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
newPod := validPod("123", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error because the pod exceeded allowed quota")
|
t.Errorf("Expected an error because the pod exceeded allowed quota")
|
||||||
}
|
}
|
||||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "subresource", admission.Create, nil))
|
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "subresource", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Did not expect an error because the action went to a subresource: %v", err)
|
t.Errorf("Did not expect an error because the action went to a subresource: %v", err)
|
||||||
}
|
}
|
||||||
@ -232,7 +232,7 @@ func TestAdmitBelowQuotaLimit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -278,6 +278,59 @@ func TestAdmitBelowQuotaLimit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAdmitDryRun verifies that a pod when created with dry-run doesn not have its usage reflected on the quota
|
||||||
|
// and that dry-run requests can still be rejected if they would exceed the quota
|
||||||
|
func TestAdmitDryRun(t *testing.T) {
|
||||||
|
resourceQuota := &api.ResourceQuota{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "quota", Namespace: "test", ResourceVersion: "124"},
|
||||||
|
Status: api.ResourceQuotaStatus{
|
||||||
|
Hard: api.ResourceList{
|
||||||
|
api.ResourceCPU: resource.MustParse("3"),
|
||||||
|
api.ResourceMemory: resource.MustParse("100Gi"),
|
||||||
|
api.ResourcePods: resource.MustParse("5"),
|
||||||
|
},
|
||||||
|
Used: api.ResourceList{
|
||||||
|
api.ResourceCPU: resource.MustParse("1"),
|
||||||
|
api.ResourceMemory: resource.MustParse("50Gi"),
|
||||||
|
api.ResourcePods: resource.MustParse("3"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
|
||||||
|
kubeClient := fake.NewSimpleClientset(resourceQuota)
|
||||||
|
informerFactory := informers.NewSharedInformerFactory(kubeClient, controller.NoResyncPeriodFunc())
|
||||||
|
quotaAccessor, _ := newQuotaAccessor()
|
||||||
|
quotaAccessor.client = kubeClient
|
||||||
|
quotaAccessor.lister = informerFactory.Core().InternalVersion().ResourceQuotas().Lister()
|
||||||
|
config := &resourcequotaapi.Configuration{}
|
||||||
|
quotaConfiguration := install.NewQuotaConfigurationForAdmission()
|
||||||
|
evaluator := NewQuotaEvaluator(quotaAccessor, quotaConfiguration.IgnoredResources(), generic.NewRegistry(quotaConfiguration.Evaluators()), nil, config, 5, stopCh)
|
||||||
|
|
||||||
|
handler := &QuotaAdmission{
|
||||||
|
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||||
|
evaluator: evaluator,
|
||||||
|
}
|
||||||
|
informerFactory.Core().InternalVersion().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, api.Resource("pods").WithVersion("version"), "", admission.Create, true, 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, api.Resource("pods").WithVersion("version"), "", admission.Create, true, nil))
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error but got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(kubeClient.Actions()) != 0 {
|
||||||
|
t.Errorf("Expected no client action on dry-run")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestAdmitHandlesOldObjects verifies that admit handles updates correctly with old objects
|
// TestAdmitHandlesOldObjects verifies that admit handles updates correctly with old objects
|
||||||
func TestAdmitHandlesOldObjects(t *testing.T) {
|
func TestAdmitHandlesOldObjects(t *testing.T) {
|
||||||
// in this scenario, the old quota was based on a service type=loadbalancer
|
// in this scenario, the old quota was based on a service type=loadbalancer
|
||||||
@ -328,7 +381,7 @@ func TestAdmitHandlesOldObjects(t *testing.T) {
|
|||||||
Ports: []api.ServicePort{{Port: 1234}},
|
Ports: []api.ServicePort{{Port: 1234}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -437,7 +490,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -504,7 +557,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil))
|
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -601,7 +654,7 @@ func TestAdmitHandlesCreatingUpdates(t *testing.T) {
|
|||||||
Ports: []api.ServicePort{{Port: 1234}},
|
Ports: []api.ServicePort{{Port: 1234}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -684,7 +737,7 @@ func TestAdmitExceedQuotaLimit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error exceeding quota")
|
t.Errorf("Expected an error exceeding quota")
|
||||||
}
|
}
|
||||||
@ -730,7 +783,7 @@ func TestAdmitEnforceQuotaConstraints(t *testing.T) {
|
|||||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||||
// verify all values are specified as required on the quota
|
// verify all values are specified as required on the quota
|
||||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error because the pod does not specify a memory limit")
|
t.Errorf("Expected an error because the pod does not specify a memory limit")
|
||||||
}
|
}
|
||||||
@ -781,7 +834,7 @@ func TestAdmitPodInNamespaceWithoutQuota(t *testing.T) {
|
|||||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
||||||
// Add to the lru cache so we do not do a live client lookup
|
// Add to the lru cache so we do not do a live client lookup
|
||||||
liveLookupCache.Add(newPod.Namespace, liveLookupEntry{expiry: time.Now().Add(time.Duration(30 * time.Second)), items: []*api.ResourceQuota{}})
|
liveLookupCache.Add(newPod.Namespace, liveLookupEntry{expiry: time.Now().Add(time.Duration(30 * time.Second)), items: []*api.ResourceQuota{}})
|
||||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Did not expect an error because the pod is in a different namespace than the quota")
|
t.Errorf("Did not expect an error because the pod is in a different namespace than the quota")
|
||||||
}
|
}
|
||||||
@ -850,7 +903,7 @@ func TestAdmitBelowTerminatingQuotaLimit(t *testing.T) {
|
|||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||||
activeDeadlineSeconds := int64(30)
|
activeDeadlineSeconds := int64(30)
|
||||||
newPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
|
newPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -954,7 +1007,7 @@ func TestAdmitBelowBestEffortQuotaLimit(t *testing.T) {
|
|||||||
|
|
||||||
// create a pod that is best effort because it does not make a request for anything
|
// create a pod that is best effort because it does not make a request for anything
|
||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1044,7 +1097,7 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "1Gi"), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "1Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1134,7 +1187,7 @@ func TestAdmissionSetsMissingNamespace(t *testing.T) {
|
|||||||
// unset the namespace
|
// unset the namespace
|
||||||
newPod.ObjectMeta.Namespace = ""
|
newPod.ObjectMeta.Namespace = ""
|
||||||
|
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Got unexpected error: %v", err)
|
t.Errorf("Got unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1177,14 +1230,14 @@ func TestAdmitRejectsNegativeUsage(t *testing.T) {
|
|||||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||||
// verify quota rejects negative pvc storage requests
|
// verify quota rejects negative pvc storage requests
|
||||||
newPvc := validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("-1Gi")}, api.ResourceList{}))
|
newPvc := validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("-1Gi")}, api.ResourceList{}))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error because the pvc has negative storage usage")
|
t.Errorf("Expected an error because the pvc has negative storage usage")
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify quota accepts non-negative pvc storage requests
|
// verify quota accepts non-negative pvc storage requests
|
||||||
newPvc = validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("1Gi")}, api.ResourceList{}))
|
newPvc = validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("1Gi")}, api.ResourceList{}))
|
||||||
err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1225,7 +1278,7 @@ func TestAdmitWhenUnrelatedResourceExceedsQuota(t *testing.T) {
|
|||||||
|
|
||||||
// create a pod that should pass existing quota
|
// create a pod that should pass existing quota
|
||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1259,7 +1312,7 @@ func TestAdmitLimitedResourceNoQuota(t *testing.T) {
|
|||||||
evaluator: evaluator,
|
evaluator: evaluator,
|
||||||
}
|
}
|
||||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error for consuming a limited resource without quota.")
|
t.Errorf("Expected an error for consuming a limited resource without quota.")
|
||||||
}
|
}
|
||||||
@ -1293,7 +1346,7 @@ func TestAdmitLimitedResourceNoQuotaIgnoresNonMatchingResources(t *testing.T) {
|
|||||||
evaluator: evaluator,
|
evaluator: evaluator,
|
||||||
}
|
}
|
||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1341,7 +1394,7 @@ func TestAdmitLimitedResourceWithQuota(t *testing.T) {
|
|||||||
}
|
}
|
||||||
indexer.Add(resourceQuota)
|
indexer.Add(resourceQuota)
|
||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1401,7 +1454,7 @@ func TestAdmitLimitedResourceWithMultipleQuota(t *testing.T) {
|
|||||||
indexer.Add(resourceQuota1)
|
indexer.Add(resourceQuota1)
|
||||||
indexer.Add(resourceQuota2)
|
indexer.Add(resourceQuota2)
|
||||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1449,7 +1502,7 @@ func TestAdmitLimitedResourceWithQuotaThatDoesNotCover(t *testing.T) {
|
|||||||
}
|
}
|
||||||
indexer.Add(resourceQuota)
|
indexer.Add(resourceQuota)
|
||||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Expected an error since the quota did not cover cpu")
|
t.Fatalf("Expected an error since the quota did not cover cpu")
|
||||||
}
|
}
|
||||||
@ -2110,7 +2163,7 @@ func TestAdmitLimitedScopeWithCoverQuota(t *testing.T) {
|
|||||||
if testCase.anotherQuota != nil {
|
if testCase.anotherQuota != nil {
|
||||||
indexer.Add(testCase.anotherQuota)
|
indexer.Add(testCase.anotherQuota)
|
||||||
}
|
}
|
||||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if testCase.expErr == "" {
|
if testCase.expErr == "" {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Testcase, %v, failed with unexpected error: %v. ExpErr: %v", testCase.description, err, testCase.expErr)
|
t.Fatalf("Testcase, %v, failed with unexpected error: %v. ExpErr: %v", testCase.description, err, testCase.expErr)
|
||||||
|
@ -231,6 +231,12 @@ func (e *quotaEvaluator) checkQuotas(quotas []api.ResourceQuota, admissionAttrib
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't update quota for admissionAttributes that correspond to dry-run requests
|
||||||
|
if admissionAttribute.attributes.IsDryRun() {
|
||||||
|
admissionAttribute.result = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// if the new quotas are the same as the old quotas, then this particular one doesn't issue any updates
|
// if the new quotas are the same as the old quotas, then this particular one doesn't issue any updates
|
||||||
// that means that no quota docs applied, so it can get a pass
|
// that means that no quota docs applied, so it can get a pass
|
||||||
atLeastOneChangeForThisWaiter := false
|
atLeastOneChangeForThisWaiter := false
|
||||||
|
@ -472,7 +472,7 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
|||||||
func TestFailClosedOnInvalidPod(t *testing.T) {
|
func TestFailClosedOnInvalidPod(t *testing.T) {
|
||||||
plugin := NewTestAdmission(nil, nil)
|
plugin := NewTestAdmission(nil, nil)
|
||||||
pod := &v1.Pod{}
|
pod := &v1.Pod{}
|
||||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{})
|
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
err := plugin.Admit(attrs)
|
err := plugin.Admit(attrs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -1769,7 +1769,7 @@ func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*
|
|||||||
originalPod := pod.DeepCopy()
|
originalPod := pod.DeepCopy()
|
||||||
plugin := NewTestAdmission(psps, authz)
|
plugin := NewTestAdmission(psps, authz)
|
||||||
|
|
||||||
attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, userInfo)
|
attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, false, userInfo)
|
||||||
annotations := make(map[string]string)
|
annotations := make(map[string]string)
|
||||||
attrs = &fakeAttributes{attrs, annotations}
|
attrs = &fakeAttributes{attrs, annotations}
|
||||||
err := plugin.Admit(attrs)
|
err := plugin.Admit(attrs)
|
||||||
@ -2227,7 +2227,7 @@ func TestPolicyAuthorizationErrors(t *testing.T) {
|
|||||||
pod.Spec.SecurityContext.HostPID = true
|
pod.Spec.SecurityContext.HostPID = true
|
||||||
|
|
||||||
plugin := NewTestAdmission(tc.inPolicies, authz)
|
plugin := NewTestAdmission(tc.inPolicies, authz)
|
||||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{Name: userName})
|
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, false, &user.DefaultInfo{Name: userName})
|
||||||
|
|
||||||
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true, "")
|
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true, "")
|
||||||
assert.Nil(t, allowedPod)
|
assert.Nil(t, allowedPod)
|
||||||
@ -2320,7 +2320,7 @@ func TestPreferValidatedPSP(t *testing.T) {
|
|||||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation
|
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation
|
||||||
|
|
||||||
plugin := NewTestAdmission(tc.inPolicies, authz)
|
plugin := NewTestAdmission(tc.inPolicies, authz)
|
||||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, &user.DefaultInfo{Name: "test"})
|
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, false, &user.DefaultInfo{Name: "test"})
|
||||||
|
|
||||||
_, pspName, validationErrs, err := plugin.computeSecurityContext(attrs, pod, false, tc.validatedPSPHint)
|
_, pspName, validationErrs, err := plugin.computeSecurityContext(attrs, pod, false, tc.validatedPSPHint)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -82,7 +82,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
p.Spec.SecurityContext = tc.podSc
|
p.Spec.SecurityContext = tc.podSc
|
||||||
p.Spec.Containers[0].SecurityContext = tc.sc
|
p.Spec.Containers[0].SecurityContext = tc.sc
|
||||||
|
|
||||||
err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||||
if err != nil && !tc.expectError {
|
if err != nil && !tc.expectError {
|
||||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||||
} else if err == nil && tc.expectError {
|
} else if err == nil && tc.expectError {
|
||||||
@ -96,7 +96,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
p.Spec.InitContainers = p.Spec.Containers
|
p.Spec.InitContainers = p.Spec.Containers
|
||||||
p.Spec.Containers = nil
|
p.Spec.Containers = nil
|
||||||
|
|
||||||
err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||||
if err != nil && !tc.expectError {
|
if err != nil && !tc.expectError {
|
||||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||||
} else if err == nil && tc.expectError {
|
} else if err == nil && tc.expectError {
|
||||||
@ -140,7 +140,7 @@ func TestPodSecurityContextAdmission(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
pod.Spec.SecurityContext = &test.securityContext
|
pod.Spec.SecurityContext = &test.securityContext
|
||||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||||
|
|
||||||
if test.errorExpected && err == nil {
|
if test.errorExpected && err == nil {
|
||||||
t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext)
|
t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext)
|
||||||
|
@ -46,7 +46,7 @@ func TestIgnoresNonCreate(t *testing.T) {
|
|||||||
func TestIgnoresUpdateOfInitializedPod(t *testing.T) {
|
func TestIgnoresUpdateOfInitializedPod(t *testing.T) {
|
||||||
pod := &api.Pod{}
|
pod := &api.Pod{}
|
||||||
oldPod := &api.Pod{}
|
oldPod := &api.Pod{}
|
||||||
attrs := admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, nil)
|
attrs := admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil)
|
||||||
handler := NewServiceAccount()
|
handler := NewServiceAccount()
|
||||||
err := handler.Admit(attrs)
|
err := handler.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -56,7 +56,7 @@ func TestIgnoresUpdateOfInitializedPod(t *testing.T) {
|
|||||||
|
|
||||||
func TestIgnoresNonPodResource(t *testing.T) {
|
func TestIgnoresNonPodResource(t *testing.T) {
|
||||||
pod := &api.Pod{}
|
pod := &api.Pod{}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("CustomResource").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("CustomResource").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := NewServiceAccount().Admit(attrs)
|
err := NewServiceAccount().Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected non-pod resource allowed, got err: %v", err)
|
t.Errorf("Expected non-pod resource allowed, got err: %v", err)
|
||||||
@ -64,7 +64,7 @@ func TestIgnoresNonPodResource(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIgnoresNilObject(t *testing.T) {
|
func TestIgnoresNilObject(t *testing.T) {
|
||||||
attrs := admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := NewServiceAccount().Admit(attrs)
|
err := NewServiceAccount().Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected nil object allowed allowed, got err: %v", err)
|
t.Errorf("Expected nil object allowed allowed, got err: %v", err)
|
||||||
@ -73,7 +73,7 @@ func TestIgnoresNilObject(t *testing.T) {
|
|||||||
|
|
||||||
func TestIgnoresNonPodObject(t *testing.T) {
|
func TestIgnoresNonPodObject(t *testing.T) {
|
||||||
obj := &api.Namespace{}
|
obj := &api.Namespace{}
|
||||||
attrs := admission.NewAttributesRecord(obj, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(obj, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := NewServiceAccount().Admit(attrs)
|
err := NewServiceAccount().Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected non pod object allowed, got err: %v", err)
|
t.Errorf("Expected non pod object allowed, got err: %v", err)
|
||||||
@ -93,7 +93,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, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := NewServiceAccount().Admit(attrs)
|
err := NewServiceAccount().Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected mirror pod without service account or secrets allowed, got err: %v", err)
|
t.Errorf("Expected mirror pod without service account or secrets allowed, got err: %v", err)
|
||||||
@ -111,7 +111,7 @@ func TestRejectsMirrorPodWithServiceAccount(t *testing.T) {
|
|||||||
ServiceAccountName: "default",
|
ServiceAccountName: "default",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := NewServiceAccount().Admit(attrs)
|
err := NewServiceAccount().Admit(attrs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected a mirror pod to be prevented from referencing a service account")
|
t.Errorf("Expected a mirror pod to be prevented from referencing a service account")
|
||||||
@ -131,7 +131,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, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := NewServiceAccount().Admit(attrs)
|
err := NewServiceAccount().Admit(attrs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected a mirror pod to be prevented from referencing a secret volume")
|
t.Errorf("Expected a mirror pod to be prevented from referencing a secret volume")
|
||||||
@ -156,7 +156,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, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := NewServiceAccount().Admit(attrs)
|
err := NewServiceAccount().Admit(attrs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected a mirror pod to be prevented from referencing a ServiceAccountToken volume projection")
|
t.Errorf("Expected a mirror pod to be prevented from referencing a ServiceAccountToken volume projection")
|
||||||
@ -181,7 +181,7 @@ func TestAssignsDefaultServiceAccountAndToleratesMissingAPIToken(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
pod := &api.Pod{}
|
pod := &api.Pod{}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -209,7 +209,7 @@ func TestAssignsDefaultServiceAccountAndRejectsMissingAPIToken(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
pod := &api.Pod{}
|
pod := &api.Pod{}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err == nil || !errors.IsServerTimeout(err) {
|
if err == nil || !errors.IsServerTimeout(err) {
|
||||||
t.Errorf("Expected server timeout error for missing API token: %v", err)
|
t.Errorf("Expected server timeout error for missing API token: %v", err)
|
||||||
@ -234,7 +234,7 @@ func TestFetchesUncachedServiceAccount(t *testing.T) {
|
|||||||
admit.RequireAPIToken = false
|
admit.RequireAPIToken = false
|
||||||
|
|
||||||
pod := &api.Pod{}
|
pod := &api.Pod{}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -256,7 +256,7 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
|
|||||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||||
|
|
||||||
pod := &api.Pod{}
|
pod := &api.Pod{}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error for missing service account, got none")
|
t.Errorf("Expected error for missing service account, got none")
|
||||||
@ -321,7 +321,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, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -369,7 +369,7 @@ func TestAutomountsAPIToken(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
attrs = admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, nil)
|
attrs = admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil)
|
||||||
err = admit.Admit(attrs)
|
err = admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -398,7 +398,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, nil)
|
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err != nil {
|
if err := admit.Admit(attrs); err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -478,7 +478,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, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -508,7 +508,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, nil)
|
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err != nil {
|
if err := admit.Admit(attrs); err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -553,7 +553,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, nil)
|
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err != nil {
|
if err := admit.Admit(attrs); err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -577,7 +577,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, nil)
|
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err != nil {
|
if err := admit.Admit(attrs); err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -601,7 +601,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, nil)
|
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err != nil {
|
if err := admit.Admit(attrs); err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -631,7 +631,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, nil)
|
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err == nil {
|
if err := admit.Admit(attrs); err == nil {
|
||||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||||
}
|
}
|
||||||
@ -655,7 +655,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, nil)
|
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -679,7 +679,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, nil)
|
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -710,7 +710,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, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||||
@ -742,7 +742,7 @@ func TestAllowsReferencedImagePullSecrets(t *testing.T) {
|
|||||||
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -771,7 +771,7 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) {
|
|||||||
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||||
@ -804,7 +804,7 @@ func TestDoNotAddImagePullSecrets(t *testing.T) {
|
|||||||
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -838,7 +838,7 @@ func TestAddImagePullSecrets(t *testing.T) {
|
|||||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(sa)
|
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(sa)
|
||||||
|
|
||||||
pod := &api.Pod{}
|
pod := &api.Pod{}
|
||||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
err := admit.Admit(attrs)
|
err := admit.Admit(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -921,7 +921,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, nil)
|
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||||
if err := admit.Admit(attrs); err != nil {
|
if err := admit.Admit(attrs); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -126,20 +126,20 @@ func TestAdmission(t *testing.T) {
|
|||||||
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
|
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
|
||||||
|
|
||||||
// Non-cloud PVs are ignored
|
// Non-cloud PVs are ignored
|
||||||
err := handler.Admit(admission.NewAttributesRecord(&ignoredPV, nil, api.Kind("PersistentVolume").WithVersion("version"), ignoredPV.Namespace, ignoredPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err := handler.Admit(admission.NewAttributesRecord(&ignoredPV, nil, api.Kind("PersistentVolume").WithVersion("version"), ignoredPV.Namespace, ignoredPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler (on ignored pv): %v", err)
|
t.Errorf("Unexpected error returned from admission handler (on ignored pv): %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only add labels on creation
|
// We only add labels on creation
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Delete, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Delete, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler (when deleting aws pv): %v", err)
|
t.Errorf("Unexpected error returned from admission handler (when deleting aws pv): %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errors from the cloudprovider block creation of the volume
|
// Errors from the cloudprovider block creation of the volume
|
||||||
pvHandler.ebsVolumes = mockVolumeFailure(fmt.Errorf("invalid volume"))
|
pvHandler.ebsVolumes = mockVolumeFailure(fmt.Errorf("invalid volume"))
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error when aws pv info fails")
|
t.Errorf("Expected error when aws pv info fails")
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
// Don't add labels if the cloudprovider doesn't return any
|
// Don't add labels if the cloudprovider doesn't return any
|
||||||
labels := make(map[string]string)
|
labels := make(map[string]string)
|
||||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error when creating aws pv")
|
t.Errorf("Expected no error when creating aws pv")
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
|
|
||||||
// Don't panic if the cloudprovider returns nil, nil
|
// Don't panic if the cloudprovider returns nil, nil
|
||||||
pvHandler.ebsVolumes = mockVolumeFailure(nil)
|
pvHandler.ebsVolumes = mockVolumeFailure(nil)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error when cloud provider returns empty labels")
|
t.Errorf("Expected no error when cloud provider returns empty labels")
|
||||||
}
|
}
|
||||||
@ -172,7 +172,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
zones, _ := volumeutil.ZonesToSet("1,2,3")
|
zones, _ := volumeutil.ZonesToSet("1,2,3")
|
||||||
labels[kubeletapis.LabelZoneFailureDomain] = volumeutil.ZonesSetToLabelValue(zones)
|
labels[kubeletapis.LabelZoneFailureDomain] = volumeutil.ZonesSetToLabelValue(zones)
|
||||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error when creating aws pv")
|
t.Errorf("Expected no error when creating aws pv")
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
awsPV.ObjectMeta.Labels = make(map[string]string)
|
awsPV.ObjectMeta.Labels = make(map[string]string)
|
||||||
awsPV.ObjectMeta.Labels["a"] = "not1"
|
awsPV.ObjectMeta.Labels["a"] = "not1"
|
||||||
awsPV.ObjectMeta.Labels["c"] = "3"
|
awsPV.ObjectMeta.Labels["c"] = "3"
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error when creating aws pv")
|
t.Errorf("Expected no error when creating aws pv")
|
||||||
}
|
}
|
||||||
@ -227,7 +227,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
labels["b"] = "2"
|
labels["b"] = "2"
|
||||||
labels["c"] = "3"
|
labels["c"] = "3"
|
||||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error when creating aws pv")
|
t.Errorf("Expected no error when creating aws pv")
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
labels["f"] = "2"
|
labels["f"] = "2"
|
||||||
labels["g"] = "3"
|
labels["g"] = "3"
|
||||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error when creating aws pv")
|
t.Errorf("Expected no error when creating aws pv")
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ func TestPVCResizeAdmission(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
operation := admission.Update
|
operation := admission.Update
|
||||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, nil)
|
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, nil)
|
||||||
|
|
||||||
err := ctrl.Validate(attributes)
|
err := ctrl.Validate(attributes)
|
||||||
fmt.Println(tc.name)
|
fmt.Println(tc.name)
|
||||||
|
@ -208,6 +208,7 @@ func TestAdmission(t *testing.T) {
|
|||||||
api.Resource("persistentvolumeclaims").WithVersion("version"),
|
api.Resource("persistentvolumeclaims").WithVersion("version"),
|
||||||
"", // subresource
|
"", // subresource
|
||||||
admission.Create,
|
admission.Create,
|
||||||
|
false, // dryRun
|
||||||
nil, // userInfo
|
nil, // userInfo
|
||||||
)
|
)
|
||||||
err := ctrl.Admit(attrs)
|
err := ctrl.Admit(attrs)
|
||||||
|
@ -133,6 +133,7 @@ func TestAdmit(t *testing.T) {
|
|||||||
test.resource,
|
test.resource,
|
||||||
"", // subresource
|
"", // subresource
|
||||||
admission.Create,
|
admission.Create,
|
||||||
|
false, // dryRun
|
||||||
nil, // userInfo
|
nil, // userInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ type attributesRecord struct {
|
|||||||
resource schema.GroupVersionResource
|
resource schema.GroupVersionResource
|
||||||
subresource string
|
subresource string
|
||||||
operation Operation
|
operation Operation
|
||||||
|
dryRun bool
|
||||||
object runtime.Object
|
object runtime.Object
|
||||||
oldObject runtime.Object
|
oldObject runtime.Object
|
||||||
userInfo user.Info
|
userInfo user.Info
|
||||||
@ -44,7 +45,7 @@ type attributesRecord struct {
|
|||||||
annotationsLock sync.RWMutex
|
annotationsLock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAttributesRecord(object runtime.Object, oldObject runtime.Object, kind schema.GroupVersionKind, namespace, name string, resource schema.GroupVersionResource, subresource string, operation Operation, 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, dryRun bool, userInfo user.Info) Attributes {
|
||||||
return &attributesRecord{
|
return &attributesRecord{
|
||||||
kind: kind,
|
kind: kind,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
@ -52,6 +53,7 @@ func NewAttributesRecord(object runtime.Object, oldObject runtime.Object, kind s
|
|||||||
resource: resource,
|
resource: resource,
|
||||||
subresource: subresource,
|
subresource: subresource,
|
||||||
operation: operation,
|
operation: operation,
|
||||||
|
dryRun: dryRun,
|
||||||
object: object,
|
object: object,
|
||||||
oldObject: oldObject,
|
oldObject: oldObject,
|
||||||
userInfo: userInfo,
|
userInfo: userInfo,
|
||||||
@ -82,6 +84,10 @@ func (record *attributesRecord) GetOperation() Operation {
|
|||||||
return record.operation
|
return record.operation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (record *attributesRecord) IsDryRun() bool {
|
||||||
|
return record.dryRun
|
||||||
|
}
|
||||||
|
|
||||||
func (record *attributesRecord) GetObject() runtime.Object {
|
func (record *attributesRecord) GetObject() runtime.Object {
|
||||||
return record.object
|
return record.object
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ func (h fakeHandler) Handles(o Operation) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func attributes() Attributes {
|
func attributes() Attributes {
|
||||||
return NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", "", nil)
|
return NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", "", false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithAudit(t *testing.T) {
|
func TestWithAudit(t *testing.T) {
|
||||||
|
@ -119,7 +119,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Logf("testcase = %s", test.name)
|
t.Logf("testcase = %s", test.name)
|
||||||
// call admit and check that validate was not called at all
|
// call admit and check that validate was not called at all
|
||||||
err := test.chain.Admit(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, nil))
|
err := test.chain.Admit(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||||
accepted := (err == nil)
|
accepted := (err == nil)
|
||||||
if accepted != test.accept {
|
if accepted != test.accept {
|
||||||
t.Errorf("unexpected result of admit call: %v", accepted)
|
t.Errorf("unexpected result of admit call: %v", accepted)
|
||||||
@ -140,7 +140,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call validate and check that admit was not called at all
|
// call validate and check that admit was not called at all
|
||||||
err = test.chain.Validate(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, nil))
|
err = test.chain.Validate(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||||
accepted = (err == nil)
|
accepted = (err == nil)
|
||||||
if accepted != test.accept {
|
if accepted != test.accept {
|
||||||
t.Errorf("unexpected result of validate call: %v\n", accepted)
|
t.Errorf("unexpected result of validate call: %v\n", accepted)
|
||||||
|
@ -36,6 +36,7 @@ func TestNewForbidden(t *testing.T) {
|
|||||||
schema.GroupVersionResource{Group: "foo", Version: "bar", Resource: "baz"},
|
schema.GroupVersionResource{Group: "foo", Version: "bar", Resource: "baz"},
|
||||||
"",
|
"",
|
||||||
Create,
|
Create,
|
||||||
|
false,
|
||||||
nil)
|
nil)
|
||||||
err := errors.New("some error")
|
err := errors.New("some error")
|
||||||
expectedErr := `baz.foo "Unknown/errorGettingName" is forbidden: some error`
|
expectedErr := `baz.foo "Unknown/errorGettingName" is forbidden: some error`
|
||||||
|
@ -41,6 +41,11 @@ type Attributes interface {
|
|||||||
GetSubresource() string
|
GetSubresource() string
|
||||||
// GetOperation is the operation being performed
|
// GetOperation is the operation being performed
|
||||||
GetOperation() Operation
|
GetOperation() Operation
|
||||||
|
// 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
|
||||||
|
// could still be rejected by a subsequent validation step.
|
||||||
|
IsDryRun() bool
|
||||||
// GetObject is the object from the incoming request prior to default values being applied
|
// GetObject is the object from the incoming request prior to default values being applied
|
||||||
GetObject() runtime.Object
|
GetObject() runtime.Object
|
||||||
// GetOldObject is the existing object. Only populated for UPDATE requests.
|
// GetOldObject is the existing object. Only populated for UPDATE requests.
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
kind = schema.GroupVersionKind{Group: "kgroup", Version: "kversion", Kind: "kind"}
|
kind = schema.GroupVersionKind{Group: "kgroup", Version: "kversion", Kind: "kind"}
|
||||||
resource = schema.GroupVersionResource{Group: "rgroup", Version: "rversion", Resource: "resource"}
|
resource = schema.GroupVersionResource{Group: "rgroup", Version: "rversion", Resource: "resource"}
|
||||||
attr = admission.NewAttributesRecord(nil, nil, kind, "ns", "name", resource, "subresource", admission.Create, nil)
|
attr = admission.NewAttributesRecord(nil, nil, kind, "ns", "name", resource, "subresource", admission.Create, false, nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestObserveAdmissionStep(t *testing.T) {
|
func TestObserveAdmissionStep(t *testing.T) {
|
||||||
@ -156,7 +156,7 @@ func TestWithMetrics(t *testing.T) {
|
|||||||
h := WithMetrics(test.handler, Metrics.ObserveAdmissionController, test.name)
|
h := WithMetrics(test.handler, Metrics.ObserveAdmissionController, test.name)
|
||||||
|
|
||||||
// test mutation
|
// test mutation
|
||||||
err := h.(admission.MutationInterface).Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, nil))
|
err := h.(admission.MutationInterface).Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||||
if test.admit && err != nil {
|
if test.admit && err != nil {
|
||||||
t.Errorf("expected admit to succeed, but failed: %v", err)
|
t.Errorf("expected admit to succeed, but failed: %v", err)
|
||||||
continue
|
continue
|
||||||
@ -181,7 +181,7 @@ func TestWithMetrics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test validation
|
// test validation
|
||||||
err = h.(admission.ValidationInterface).Validate(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, nil))
|
err = h.(admission.ValidationInterface).Validate(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||||
if test.validate && err != nil {
|
if test.validate && err != nil {
|
||||||
t.Errorf("expected admit to succeed, but failed: %v", err)
|
t.Errorf("expected admit to succeed, but failed: %v", err)
|
||||||
continue
|
continue
|
||||||
|
@ -179,7 +179,7 @@ func TestAdmitUpdate(t *testing.T) {
|
|||||||
oldObj.Initializers = tc.oldInitializers
|
oldObj.Initializers = tc.oldInitializers
|
||||||
newObj := &v1.Pod{}
|
newObj := &v1.Pod{}
|
||||||
newObj.Initializers = tc.newInitializers
|
newObj.Initializers = tc.newInitializers
|
||||||
a := admission.NewAttributesRecord(newObj, oldObj, schema.GroupVersionKind{}, "", "foo", schema.GroupVersionResource{}, "", admission.Update, nil)
|
a := admission.NewAttributesRecord(newObj, oldObj, schema.GroupVersionKind{}, "", "foo", schema.GroupVersionResource{}, "", admission.Update, false, nil)
|
||||||
err := plugin.Admit(a)
|
err := plugin.Admit(a)
|
||||||
switch {
|
switch {
|
||||||
case tc.err == "" && err != nil:
|
case tc.err == "" && err != nil:
|
||||||
|
@ -104,7 +104,7 @@ func TestAccessReviewCheckOnMissingNamespace(t *testing.T) {
|
|||||||
}
|
}
|
||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "LocalSubjectAccesReview"}, namespace, "", schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "localsubjectaccessreviews"}, "", admission.Create, 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, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
actions := ""
|
actions := ""
|
||||||
for _, action := range mockClient.Actions() {
|
for _, action := range mockClient.Actions() {
|
||||||
@ -134,19 +134,19 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// verify create operations in the namespace cause an error
|
// verify create operations in the namespace cause an error
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error rejecting creates in a namespace when it is missing")
|
t.Errorf("Expected error rejecting creates in a namespace when it is missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify update operations in the namespace cause an error
|
// verify update operations in the namespace cause an error
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, 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, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error rejecting updates in a namespace when it is missing")
|
t.Errorf("Expected error rejecting updates in a namespace when it is missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify delete operations in the namespace can proceed
|
// verify delete operations in the namespace can proceed
|
||||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, 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, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ func TestAdmissionNamespaceActive(t *testing.T) {
|
|||||||
informerFactory.Start(wait.NeverStop)
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error returned from admission handler")
|
t.Errorf("unexpected error returned from admission handler")
|
||||||
}
|
}
|
||||||
@ -187,31 +187,31 @@ func TestAdmissionNamespaceTerminating(t *testing.T) {
|
|||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
// verify create operations in the namespace cause an error
|
// verify create operations in the namespace cause an error
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error rejecting creates in a namespace when it is terminating")
|
t.Errorf("Expected error rejecting creates in a namespace when it is terminating")
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify update operations in the namespace can proceed
|
// verify update operations in the namespace can proceed
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, 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, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify delete operations in the namespace can proceed
|
// verify delete operations in the namespace can proceed
|
||||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, 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, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify delete of namespace default can never proceed
|
// verify delete of namespace default can never proceed
|
||||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", metav1.NamespaceDefault, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, nil))
|
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))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error that this namespace can never be deleted")
|
t.Errorf("Expected an error that this namespace can never be deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify delete of namespace other than default can proceed
|
// verify delete of namespace other than default can proceed
|
||||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", "other", v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, nil))
|
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", "other", v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Did not expect an error %v", err)
|
t.Errorf("Did not expect an error %v", err)
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
|||||||
|
|
||||||
pod := newPod(namespace)
|
pod := newPod(namespace)
|
||||||
// verify create operations in the namespace is allowed
|
// verify create operations in the namespace is allowed
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error rejecting creates in an active namespace")
|
t.Errorf("Unexpected error rejecting creates in an active namespace")
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
|||||||
getCalls = 0
|
getCalls = 0
|
||||||
|
|
||||||
// verify delete of namespace can proceed
|
// verify delete of namespace can proceed
|
||||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), namespace, namespace, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, nil))
|
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected namespace deletion to be allowed")
|
t.Errorf("Expected namespace deletion to be allowed")
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
|||||||
phases[namespace] = v1.NamespaceTerminating
|
phases[namespace] = v1.NamespaceTerminating
|
||||||
|
|
||||||
// verify create operations in the namespace cause an error
|
// verify create operations in the namespace cause an error
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
|
t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
|
||||||
}
|
}
|
||||||
@ -274,7 +274,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
|||||||
fakeClock.Step(forceLiveLookupTTL)
|
fakeClock.Step(forceLiveLookupTTL)
|
||||||
|
|
||||||
// verify create operations in the namespace cause an error
|
// verify create operations in the namespace cause an error
|
||||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
|
t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
|||||||
fakeClock.Step(time.Millisecond)
|
fakeClock.Step(time.Millisecond)
|
||||||
|
|
||||||
// verify create operations in the namespace don't force a live lookup after the timeout
|
// verify create operations in the namespace don't force a live lookup after the timeout
|
||||||
handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, 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, false, nil))
|
||||||
if getCalls != 0 {
|
if getCalls != 0 {
|
||||||
t.Errorf("Expected no live lookup of the namespace at t=forceLiveLookupTTL+1ms, got %d", getCalls)
|
t.Errorf("Expected no live lookup of the namespace at t=forceLiveLookupTTL+1ms, got %d", getCalls)
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ func TestDispatch(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
attr := generic.VersionedAttributes{
|
attr := generic.VersionedAttributes{
|
||||||
Attributes: admission.NewAttributesRecord(test.out, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", admission.Operation(""), nil),
|
Attributes: admission.NewAttributesRecord(test.out, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", admission.Operation(""), false, nil),
|
||||||
VersionedOldObject: nil,
|
VersionedOldObject: nil,
|
||||||
VersionedObject: test.in,
|
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",
|
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, nil),
|
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, "", namespace2.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Create, false, nil),
|
||||||
expectedLabels: namespace2Labels,
|
expectedLabels: namespace2Labels,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is for updating namespace, the labels should be from the new object",
|
name: "request is for updating namespace, the labels should be from the new object",
|
||||||
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace2.Name, namespace2.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Update, nil),
|
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace2.Name, namespace2.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Update, false, nil),
|
||||||
expectedLabels: namespace2Labels,
|
expectedLabels: namespace2Labels,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is for deleting namespace, the labels should be from the cache",
|
name: "request is for deleting namespace, the labels should be from the cache",
|
||||||
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace1.Name, namespace1.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Delete, nil),
|
attr: admission.NewAttributesRecord(&namespace2, nil, schema.GroupVersionKind{}, namespace1.Name, namespace1.Name, schema.GroupVersionResource{Resource: "namespaces"}, "", admission.Delete, false, nil),
|
||||||
expectedLabels: namespace1Labels,
|
expectedLabels: namespace1Labels,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is for namespace/finalizer",
|
name: "request is for namespace/finalizer",
|
||||||
attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "namespaces"}, "finalizers", admission.Create, nil),
|
attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "namespaces"}, "finalizers", admission.Create, false, nil),
|
||||||
expectedLabels: namespace1Labels,
|
expectedLabels: namespace1Labels,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is for pod",
|
name: "request is for pod",
|
||||||
attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "pods"}, "", admission.Create, nil),
|
attr: admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, namespace1.Name, "mock-name", schema.GroupVersionResource{Resource: "pods"}, "", admission.Create, false, nil),
|
||||||
expectedLabels: namespace1Labels,
|
expectedLabels: namespace1Labels,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ func TestNotExemptClusterScopedResource(t *testing.T) {
|
|||||||
hook := ®istrationv1beta1.Webhook{
|
hook := ®istrationv1beta1.Webhook{
|
||||||
NamespaceSelector: &metav1.LabelSelector{},
|
NamespaceSelector: &metav1.LabelSelector{},
|
||||||
}
|
}
|
||||||
attr := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "mock-name", schema.GroupVersionResource{Version: "v1", Resource: "nodes"}, "", admission.Create, nil)
|
attr := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, "", "mock-name", schema.GroupVersionResource{Version: "v1", Resource: "nodes"}, "", admission.Create, false, nil)
|
||||||
matcher := Matcher{}
|
matcher := Matcher{}
|
||||||
matches, err := matcher.MatchNamespaceSelector(hook, attr)
|
matches, err := matcher.MatchNamespaceSelector(hook, attr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -38,6 +38,7 @@ func a(group, version, resource, subresource, name string, operation admission.O
|
|||||||
"ns", name,
|
"ns", name,
|
||||||
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
|
schema.GroupVersionResource{Group: group, Version: version, Resource: resource}, subresource,
|
||||||
operation,
|
operation,
|
||||||
|
false,
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ func newAttributesRecord(object metav1.Object, oldObject metav1.Object, kind sch
|
|||||||
UID: "webhook-test",
|
UID: "webhook-test",
|
||||||
}
|
}
|
||||||
|
|
||||||
return admission.NewAttributesRecord(object.(runtime.Object), oldObject.(runtime.Object), kind, namespace, name, gvr, subResource, admission.Update, &userInfo)
|
return admission.NewAttributesRecord(object.(runtime.Object), oldObject.(runtime.Object), kind, namespace, name, gvr, subResource, admission.Update, false, &userInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAttribute returns static admission Attributes for testing.
|
// NewAttribute returns static admission Attributes for testing.
|
||||||
|
@ -79,6 +79,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/server/httplog:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/server/httplog:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/dryrun:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/trace:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/trace:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/wsstream:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/wsstream:go_default_library",
|
||||||
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
"k8s.io/apiserver/pkg/util/dryrun"
|
||||||
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte
|
|||||||
audit.LogRequestObject(ae, obj, scope.Resource, scope.Subresource, scope.Serializer)
|
audit.LogRequestObject(ae, obj, scope.Resource, scope.Subresource, scope.Serializer)
|
||||||
|
|
||||||
userInfo, _ := request.UserFrom(ctx)
|
userInfo, _ := request.UserFrom(ctx)
|
||||||
admissionAttributes := admission.NewAttributesRecord(obj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, userInfo)
|
admissionAttributes := admission.NewAttributesRecord(obj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) {
|
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) {
|
||||||
err = mutatingAdmission.Admit(admissionAttributes)
|
err = mutatingAdmission.Admit(admissionAttributes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
"k8s.io/apiserver/pkg/util/dryrun"
|
||||||
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
|
|||||||
trace.Step("About to check admission control")
|
trace.Step("About to check admission control")
|
||||||
if admit != nil && admit.Handles(admission.Delete) {
|
if admit != nil && admit.Handles(admission.Delete) {
|
||||||
userInfo, _ := request.UserFrom(ctx)
|
userInfo, _ := request.UserFrom(ctx)
|
||||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Delete, userInfo)
|
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||||
if err := mutatingAdmission.Admit(attrs); err != nil {
|
if err := mutatingAdmission.Admit(attrs); err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
@ -196,27 +197,6 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
ctx = request.WithNamespace(ctx, namespace)
|
ctx = request.WithNamespace(ctx, namespace)
|
||||||
ae := request.AuditEventFrom(ctx)
|
ae := request.AuditEventFrom(ctx)
|
||||||
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, userInfo)
|
|
||||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
|
||||||
err = mutatingAdmission.Admit(attrs)
|
|
||||||
if err != nil {
|
|
||||||
scope.err(err, w, req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
|
||||||
err = validatingAdmission.Validate(attrs)
|
|
||||||
if err != nil {
|
|
||||||
scope.err(err, w, req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listOptions := metainternalversion.ListOptions{}
|
listOptions := metainternalversion.ListOptions{}
|
||||||
if err := metainternalversion.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, &listOptions); err != nil {
|
if err := metainternalversion.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, &listOptions); err != nil {
|
||||||
@ -279,6 +259,27 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||||
|
err = mutatingAdmission.Admit(attrs)
|
||||||
|
if err != nil {
|
||||||
|
scope.err(err, w, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
||||||
|
err = validatingAdmission.Validate(attrs)
|
||||||
|
if err != nil {
|
||||||
|
scope.err(err, w, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result, err := finishRequest(timeout, func() (runtime.Object, error) {
|
result, err := finishRequest(timeout, func() (runtime.Object, error) {
|
||||||
return r.DeleteCollection(ctx, options, &listOptions)
|
return r.DeleteCollection(ctx, options, &listOptions)
|
||||||
})
|
})
|
||||||
|
@ -41,6 +41,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
"k8s.io/apiserver/pkg/util/dryrun"
|
||||||
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -130,6 +131,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface
|
|||||||
scope.Resource,
|
scope.Resource,
|
||||||
scope.Subresource,
|
scope.Subresource,
|
||||||
admission.Update,
|
admission.Update,
|
||||||
|
dryrun.IsDryRun(options.DryRun),
|
||||||
userInfo,
|
userInfo,
|
||||||
)
|
)
|
||||||
admissionCheck := func(updatedObject runtime.Object, currentObject runtime.Object) error {
|
admissionCheck := func(updatedObject runtime.Object, currentObject runtime.Object) error {
|
||||||
@ -144,6 +146,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface
|
|||||||
scope.Resource,
|
scope.Resource,
|
||||||
scope.Subresource,
|
scope.Subresource,
|
||||||
admission.Update,
|
admission.Update,
|
||||||
|
dryrun.IsDryRun(options.DryRun),
|
||||||
userInfo,
|
userInfo,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -123,14 +123,14 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi
|
|||||||
userInfo, _ := request.UserFrom(ctx)
|
userInfo, _ := request.UserFrom(ctx)
|
||||||
// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT
|
// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT
|
||||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||||
err = mutatingAdmission.Admit(admission.NewAttributesRecord(connectRequest, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, userInfo))
|
err = mutatingAdmission.Admit(admission.NewAttributesRecord(connectRequest, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
||||||
err = validatingAdmission.Validate(admission.NewAttributesRecord(connectRequest, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, userInfo))
|
err = validatingAdmission.Validate(admission.NewAttributesRecord(connectRequest, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.err(err, w, req)
|
scope.err(err, w, req)
|
||||||
return
|
return
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
"k8s.io/apiserver/pkg/util/dryrun"
|
||||||
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -119,11 +120,11 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac
|
|||||||
return nil, fmt.Errorf("unexpected error when extracting UID from oldObj: %v", err.Error())
|
return nil, fmt.Errorf("unexpected error when extracting UID from oldObj: %v", err.Error())
|
||||||
} else if !isNotZeroObject {
|
} else if !isNotZeroObject {
|
||||||
if mutatingAdmission.Handles(admission.Create) {
|
if mutatingAdmission.Handles(admission.Create) {
|
||||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, userInfo))
|
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if mutatingAdmission.Handles(admission.Update) {
|
if mutatingAdmission.Handles(admission.Update) {
|
||||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, userInfo))
|
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newObj, nil
|
return newObj, nil
|
||||||
@ -153,11 +154,11 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac
|
|||||||
rest.DefaultUpdatedObjectInfo(obj, transformers...),
|
rest.DefaultUpdatedObjectInfo(obj, transformers...),
|
||||||
withAuthorization(rest.AdmissionToValidateObjectFunc(
|
withAuthorization(rest.AdmissionToValidateObjectFunc(
|
||||||
admit,
|
admit,
|
||||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, userInfo)),
|
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo)),
|
||||||
scope.Authorizer, createAuthorizerAttributes),
|
scope.Authorizer, createAuthorizerAttributes),
|
||||||
rest.AdmissionToValidateObjectUpdateFunc(
|
rest.AdmissionToValidateObjectUpdateFunc(
|
||||||
admit,
|
admit,
|
||||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, userInfo)),
|
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo)),
|
||||||
false,
|
false,
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
|
@ -170,6 +170,7 @@ func AdmissionToValidateObjectFunc(admit admission.Interface, staticAttributes a
|
|||||||
staticAttributes.GetResource(),
|
staticAttributes.GetResource(),
|
||||||
staticAttributes.GetSubresource(),
|
staticAttributes.GetSubresource(),
|
||||||
staticAttributes.GetOperation(),
|
staticAttributes.GetOperation(),
|
||||||
|
staticAttributes.IsDryRun(),
|
||||||
staticAttributes.GetUserInfo(),
|
staticAttributes.GetUserInfo(),
|
||||||
)
|
)
|
||||||
if !validatingAdmission.Handles(finalAttributes.GetOperation()) {
|
if !validatingAdmission.Handles(finalAttributes.GetOperation()) {
|
||||||
|
@ -263,6 +263,7 @@ func AdmissionToValidateObjectUpdateFunc(admit admission.Interface, staticAttrib
|
|||||||
staticAttributes.GetResource(),
|
staticAttributes.GetResource(),
|
||||||
staticAttributes.GetSubresource(),
|
staticAttributes.GetSubresource(),
|
||||||
staticAttributes.GetOperation(),
|
staticAttributes.GetOperation(),
|
||||||
|
staticAttributes.IsDryRun(),
|
||||||
staticAttributes.GetUserInfo(),
|
staticAttributes.GetUserInfo(),
|
||||||
)
|
)
|
||||||
if !validatingAdmission.Handles(finalAttributes.GetOperation()) {
|
if !validatingAdmission.Handles(finalAttributes.GetOperation()) {
|
||||||
|
@ -136,6 +136,7 @@ func TestBanflunderAdmissionPlugin(t *testing.T) {
|
|||||||
scenario.admissionInputResource,
|
scenario.admissionInputResource,
|
||||||
"",
|
"",
|
||||||
admission.Create,
|
admission.Create,
|
||||||
|
false,
|
||||||
nil),
|
nil),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user