Skip to content

Commit a4576ec

Browse files
committed
Fix binding and eviction admission
1 parent 4cfa5c7 commit a4576ec

File tree

4 files changed

+72
-5
lines changed

4 files changed

+72
-5
lines changed

pkg/registry/core/pod/storage/eviction.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ func (r *EvictionREST) Create(ctx context.Context, obj runtime.Object, createVal
8787
return nil, err
8888
}
8989
pod := obj.(*api.Pod)
90+
91+
if createValidation != nil {
92+
if err := createValidation(eviction); err != nil {
93+
return nil, err
94+
}
95+
}
96+
9097
// Evicting a terminal pod should result in direct deletion of pod as it already caused disruption by the time we are evicting.
9198
// There is no need to check for pdb.
9299
if pod.Status.Phase == api.PodSucceeded || pod.Status.Phase == api.PodFailed {

pkg/registry/core/pod/storage/storage.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ func (r *BindingREST) Create(ctx context.Context, obj runtime.Object, createVali
149149
return nil, errs.ToAggregate()
150150
}
151151

152+
if createValidation != nil {
153+
if err := createValidation(binding); err != nil {
154+
return nil, err
155+
}
156+
}
157+
152158
err = r.assignPod(ctx, binding.Name, binding.Target.Name, binding.Annotations, dryrun.IsDryRun(options.DryRun))
153159
out = &metav1.Status{Status: metav1.StatusSuccess}
154160
return

test/integration/apiserver/admissionwebhook/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ go_test(
1717
"//staging/src/k8s.io/api/apps/v1beta1:go_default_library",
1818
"//staging/src/k8s.io/api/core/v1:go_default_library",
1919
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
20+
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
2021
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
2122
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
2223
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",

test/integration/apiserver/admissionwebhook/admission_test.go

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ import (
3333
"k8s.io/api/admission/v1beta1"
3434
admissionv1beta1 "k8s.io/api/admissionregistration/v1beta1"
3535
appsv1beta1 "k8s.io/api/apps/v1beta1"
36+
corev1 "k8s.io/api/core/v1"
3637
v1 "k8s.io/api/core/v1"
3738
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
39+
policyv1beta1 "k8s.io/api/policy/v1beta1"
3840
"k8s.io/apimachinery/pkg/api/errors"
3941
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4042
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -102,6 +104,10 @@ var (
102104
gvr("", "v1", "pods/exec"): {"create": testPodConnectSubresource},
103105
gvr("", "v1", "pods/portforward"): {"create": testPodConnectSubresource},
104106

107+
gvr("", "v1", "bindings"): {"create": testPodBindingEviction},
108+
gvr("", "v1", "pods/binding"): {"create": testPodBindingEviction},
109+
gvr("", "v1", "pods/eviction"): {"create": testPodBindingEviction},
110+
105111
gvr("", "v1", "nodes/proxy"): {"*": testSubresourceProxy},
106112
gvr("", "v1", "pods/proxy"): {"*": testSubresourceProxy},
107113
gvr("", "v1", "services/proxy"): {"*": testSubresourceProxy},
@@ -124,11 +130,6 @@ var (
124130
// TODO: webhook config objects are not subject to admission, verify CRUD works and webhooks do not observe them
125131
gvr("admissionregistration.k8s.io", "v1beta1", "mutatingwebhookconfigurations"): sets.NewString("*"),
126132
gvr("admissionregistration.k8s.io", "v1beta1", "validatingwebhookconfigurations"): sets.NewString("*"),
127-
128-
// TODO: implement custom subresource tests (requires special states or requests)
129-
gvr("", "v1", "bindings"): sets.NewString("create"),
130-
gvr("", "v1", "pods/binding"): sets.NewString("create"),
131-
gvr("", "v1", "pods/eviction"): sets.NewString("create"),
132133
}
133134

134135
parentResources = map[schema.GroupVersionResource]schema.GroupVersionResource{
@@ -778,6 +779,58 @@ func testPodConnectSubresource(c *testContext) {
778779
}
779780
}
780781

782+
// testPodBindingEviction verifies pod binding and eviction admission
783+
func testPodBindingEviction(c *testContext) {
784+
podGVR := gvr("", "v1", "pods")
785+
pod, err := createOrGetResource(c.client, podGVR, c.resources[podGVR])
786+
if err != nil {
787+
c.t.Error(err)
788+
return
789+
}
790+
791+
background := metav1.DeletePropagationBackground
792+
zero := int64(0)
793+
forceDelete := &metav1.DeleteOptions{GracePeriodSeconds: &zero, PropagationPolicy: &background}
794+
defer func() {
795+
err := c.clientset.CoreV1().Pods(pod.GetNamespace()).Delete(pod.GetName(), forceDelete)
796+
if err != nil && !errors.IsNotFound(err) {
797+
c.t.Error(err)
798+
return
799+
}
800+
}()
801+
802+
c.admissionHolder.expect(c.gvr, gvk(c.resource.Group, c.resource.Version, c.resource.Kind), v1beta1.Create, pod.GetName(), pod.GetNamespace(), true, false)
803+
804+
switch c.gvr {
805+
case gvr("", "v1", "bindings"):
806+
err = c.clientset.CoreV1().RESTClient().Post().Namespace(pod.GetNamespace()).Resource("bindings").Body(&corev1.Binding{
807+
ObjectMeta: metav1.ObjectMeta{Name: pod.GetName()},
808+
Target: corev1.ObjectReference{Name: "foo", Kind: "Node", APIVersion: "v1"},
809+
}).Do().Error()
810+
811+
case gvr("", "v1", "pods/binding"):
812+
err = c.clientset.CoreV1().RESTClient().Post().Namespace(pod.GetNamespace()).Resource("pods").Name(pod.GetName()).SubResource("binding").Body(&corev1.Binding{
813+
ObjectMeta: metav1.ObjectMeta{Name: pod.GetName()},
814+
Target: corev1.ObjectReference{Name: "foo", Kind: "Node", APIVersion: "v1"},
815+
}).Do().Error()
816+
817+
case gvr("", "v1", "pods/eviction"):
818+
err = c.clientset.CoreV1().RESTClient().Post().Namespace(pod.GetNamespace()).Resource("pods").Name(pod.GetName()).SubResource("eviction").Body(&policyv1beta1.Eviction{
819+
ObjectMeta: metav1.ObjectMeta{Name: pod.GetName()},
820+
DeleteOptions: forceDelete,
821+
}).Do().Error()
822+
823+
default:
824+
c.t.Errorf("unhandled resource %#v", c.gvr)
825+
return
826+
}
827+
828+
if err != nil {
829+
c.t.Error(err)
830+
return
831+
}
832+
}
833+
781834
// testSubresourceProxy verifies proxy subresources
782835
func testSubresourceProxy(c *testContext) {
783836
parentGVR := getParentGVR(c.gvr)

0 commit comments

Comments
 (0)