...
1
16
17 package admission
18
19 import (
20 "context"
21 "encoding/json"
22 "fmt"
23 "net/http"
24
25 jsonpatch "gomodules.xyz/jsonpatch/v2"
26 admissionv1 "k8s.io/api/admission/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 )
29
30 type multiMutating []Handler
31
32 func (hs multiMutating) Handle(ctx context.Context, req Request) Response {
33 patches := []jsonpatch.JsonPatchOperation{}
34 for _, handler := range hs {
35 resp := handler.Handle(ctx, req)
36 if !resp.Allowed {
37 return resp
38 }
39 if resp.PatchType != nil && *resp.PatchType != admissionv1.PatchTypeJSONPatch {
40 return Errored(http.StatusInternalServerError,
41 fmt.Errorf("unexpected patch type returned by the handler: %v, only allow: %v",
42 resp.PatchType, admissionv1.PatchTypeJSONPatch))
43 }
44 patches = append(patches, resp.Patches...)
45 }
46 var err error
47 marshaledPatch, err := json.Marshal(patches)
48 if err != nil {
49 return Errored(http.StatusBadRequest, fmt.Errorf("error when marshaling the patch: %w", err))
50 }
51 return Response{
52 AdmissionResponse: admissionv1.AdmissionResponse{
53 Allowed: true,
54 Result: &metav1.Status{
55 Code: http.StatusOK,
56 },
57 Patch: marshaledPatch,
58 PatchType: func() *admissionv1.PatchType { pt := admissionv1.PatchTypeJSONPatch; return &pt }(),
59 },
60 }
61 }
62
63
64
65
66
67 func MultiMutatingHandler(handlers ...Handler) Handler {
68 return multiMutating(handlers)
69 }
70
71 type multiValidating []Handler
72
73 func (hs multiValidating) Handle(ctx context.Context, req Request) Response {
74 for _, handler := range hs {
75 resp := handler.Handle(ctx, req)
76 if !resp.Allowed {
77 return resp
78 }
79 }
80 return Response{
81 AdmissionResponse: admissionv1.AdmissionResponse{
82 Allowed: true,
83 Result: &metav1.Status{
84 Code: http.StatusOK,
85 },
86 },
87 }
88 }
89
90
91
92
93 func MultiValidatingHandler(handlers ...Handler) Handler {
94 return multiValidating(handlers)
95 }
96
View as plain text