1
16
17 package admission
18
19 import (
20 . "github.com/onsi/ginkgo/v2"
21 . "github.com/onsi/gomega"
22
23 admissionv1 "k8s.io/api/admission/v1"
24 corev1 "k8s.io/api/core/v1"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
27 "k8s.io/apimachinery/pkg/runtime"
28 "k8s.io/client-go/kubernetes/scheme"
29 )
30
31 var _ = Describe("Admission Webhook Decoder", func() {
32 var decoder Decoder
33 BeforeEach(func() {
34 By("creating a new decoder for a scheme")
35 decoder = NewDecoder(scheme.Scheme)
36 Expect(decoder).NotTo(BeNil())
37 })
38
39 req := Request{
40 AdmissionRequest: admissionv1.AdmissionRequest{
41 Object: runtime.RawExtension{
42 Raw: []byte(`{
43 "apiVersion": "v1",
44 "kind": "Pod",
45 "metadata": {
46 "name": "foo",
47 "namespace": "default"
48 },
49 "spec": {
50 "containers": [
51 {
52 "image": "bar:v2",
53 "name": "bar"
54 }
55 ]
56 }
57 }`),
58 },
59 OldObject: runtime.RawExtension{
60 Raw: []byte(`{
61 "apiVersion": "v1",
62 "kind": "Pod",
63 "metadata": {
64 "name": "foo",
65 "namespace": "default"
66 },
67 "spec": {
68 "containers": [
69 {
70 "image": "bar:v1",
71 "name": "bar"
72 }
73 ]
74 }
75 }`),
76 },
77 },
78 }
79
80 It("should decode a valid admission request", func() {
81 By("extracting the object from the request")
82 var actualObj corev1.Pod
83 Expect(decoder.Decode(req, &actualObj)).To(Succeed())
84
85 By("verifying that all data is present in the object")
86 Expect(actualObj).To(Equal(corev1.Pod{
87 TypeMeta: metav1.TypeMeta{
88 APIVersion: "v1",
89 Kind: "Pod",
90 },
91 ObjectMeta: metav1.ObjectMeta{
92 Name: "foo",
93 Namespace: "default",
94 },
95 Spec: corev1.PodSpec{
96 Containers: []corev1.Container{
97 {Image: "bar:v2", Name: "bar"},
98 },
99 },
100 }))
101 })
102
103 It("should decode a valid RawExtension object", func() {
104 By("decoding the RawExtension object")
105 var actualObj corev1.Pod
106 Expect(decoder.DecodeRaw(req.OldObject, &actualObj)).To(Succeed())
107
108 By("verifying that all data is present in the object")
109 Expect(actualObj).To(Equal(corev1.Pod{
110 TypeMeta: metav1.TypeMeta{
111 APIVersion: "v1",
112 Kind: "Pod",
113 },
114 ObjectMeta: metav1.ObjectMeta{
115 Name: "foo",
116 Namespace: "default",
117 },
118 Spec: corev1.PodSpec{
119 Containers: []corev1.Container{
120 {Image: "bar:v1", Name: "bar"},
121 },
122 },
123 }))
124 })
125
126
127
128 It("should fail to decode if the object in the request doesn't match the passed-in type", func() {
129 By("trying to extract a pod from the quest into a node")
130 Expect(decoder.Decode(req, &corev1.Node{})).NotTo(Succeed())
131
132 By("trying to extract a pod in RawExtension format into a node")
133 Expect(decoder.DecodeRaw(req.OldObject, &corev1.Node{})).NotTo(Succeed())
134 })
135
136 It("should be able to decode into an unstructured object", func() {
137 By("decoding the request into an unstructured object")
138 var target unstructured.Unstructured
139 Expect(decoder.Decode(req, &target)).To(Succeed())
140
141 By("sanity-checking the metadata on the output object")
142 Expect(target.Object["metadata"]).To(Equal(map[string]interface{}{
143 "name": "foo",
144 "namespace": "default",
145 }))
146
147 By("decoding the RawExtension object into an unstructured object")
148 var target2 unstructured.Unstructured
149 Expect(decoder.DecodeRaw(req.Object, &target2)).To(Succeed())
150
151 By("sanity-checking the metadata on the output object")
152 Expect(target2.Object["metadata"]).To(Equal(map[string]interface{}{
153 "name": "foo",
154 "namespace": "default",
155 }))
156 })
157
158 req2 := Request{
159 AdmissionRequest: admissionv1.AdmissionRequest{
160 Operation: "CREATE",
161 Object: runtime.RawExtension{
162 Raw: []byte(`{
163 "metadata": {
164 "name": "foo",
165 "namespace": "default"
166 },
167 "spec": {
168 "containers": [
169 {
170 "image": "bar:v2",
171 "name": "bar"
172 }
173 ]
174 }
175 }`),
176 },
177 OldObject: runtime.RawExtension{
178 Object: nil,
179 },
180 },
181 }
182
183 It("should decode a valid admission request without GVK", func() {
184 By("extracting the object from the request")
185 var target3 unstructured.Unstructured
186 Expect(decoder.DecodeRaw(req2.Object, &target3)).To(Succeed())
187 })
188 })
189
View as plain text