...
1
16
17 package webhook
18
19 import (
20 v1 "k8s.io/api/admission/v1"
21 corev1 "k8s.io/api/core/v1"
22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23 "k8s.io/klog/v2"
24 )
25
26 const (
27 configMapPatch1 string = `[
28 { "op": "add", "path": "/data/mutation-stage-1", "value": "yes" }
29 ]`
30 configMapPatch2 string = `[
31 { "op": "add", "path": "/data/mutation-stage-2", "value": "yes" }
32 ]`
33 )
34
35
36 func admitConfigMaps(ar v1.AdmissionReview) *v1.AdmissionResponse {
37 klog.V(2).Info("admitting configmaps")
38 configMapResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"}
39 if ar.Request.Resource != configMapResource {
40 klog.Errorf("expect resource to be %s", configMapResource)
41 return nil
42 }
43
44 var raw []byte
45 if ar.Request.Operation == v1.Delete {
46 raw = ar.Request.OldObject.Raw
47 } else {
48 raw = ar.Request.Object.Raw
49 }
50 configmap := corev1.ConfigMap{}
51 deserializer := codecs.UniversalDeserializer()
52 if _, _, err := deserializer.Decode(raw, nil, &configmap); err != nil {
53 klog.Error(err)
54 return toV1AdmissionResponse(err)
55 }
56 reviewResponse := v1.AdmissionResponse{}
57 reviewResponse.Allowed = true
58 for k, v := range configmap.Data {
59 if k == "webhook-e2e-test" && v == "webhook-disallow" &&
60 (ar.Request.Operation == v1.Create || ar.Request.Operation == v1.Update) {
61 reviewResponse.Allowed = false
62 reviewResponse.Result = &metav1.Status{
63 Reason: "the configmap contains unwanted key and value",
64 }
65 }
66 if k == "webhook-e2e-test" && v == "webhook-nondeletable" && ar.Request.Operation == v1.Delete {
67 reviewResponse.Allowed = false
68 reviewResponse.Result = &metav1.Status{
69 Reason: "the configmap cannot be deleted because it contains unwanted key and value",
70 }
71 }
72 }
73 return &reviewResponse
74 }
75
76 func mutateConfigmaps(ar v1.AdmissionReview) *v1.AdmissionResponse {
77 klog.V(2).Info("mutating configmaps")
78 configMapResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"}
79 if ar.Request.Resource != configMapResource {
80 klog.Errorf("expect resource to be %s", configMapResource)
81 return nil
82 }
83
84 raw := ar.Request.Object.Raw
85 configmap := corev1.ConfigMap{}
86 deserializer := codecs.UniversalDeserializer()
87 if _, _, err := deserializer.Decode(raw, nil, &configmap); err != nil {
88 klog.Error(err)
89 return toV1AdmissionResponse(err)
90 }
91 reviewResponse := v1.AdmissionResponse{}
92 reviewResponse.Allowed = true
93 if configmap.Data["mutation-start"] == "yes" {
94 reviewResponse.Patch = []byte(configMapPatch1)
95 }
96 if configmap.Data["mutation-stage-1"] == "yes" {
97 reviewResponse.Patch = []byte(configMapPatch2)
98 }
99
100 if len(reviewResponse.Patch) != 0 {
101 pt := v1.PatchTypeJSONPatch
102 reviewResponse.PatchType = &pt
103 }
104
105 return &reviewResponse
106 }
107
View as plain text