66 "fmt"
77 "html/template"
88 "net/http"
9+ "strings"
910
1011 mergepatch "github.com/evanphx/json-patch"
1112 "github.com/golang/glog"
@@ -19,6 +20,7 @@ import (
1920
2021const (
2122 lastAppliedConfigPath = "/metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration"
23+ quackAnnotationPrefix = "/metadata/annotations/quack.pusher.com"
2224 leftDelimAnnotation = "quack.pusher.com/left-delim"
2325 rightDelimAnnotation = "quack.pusher.com/right-delim"
2426)
@@ -167,7 +169,7 @@ func createPatch(old []byte, new []byte) ([]byte, error) {
167169 allowedOps := []jsonpatch.JsonPatchOperation {}
168170 for _ , op := range patch {
169171 // Don't patch the lastAppliedConfig created by kubectl
170- if op .Path == lastAppliedConfigPath {
172+ if op .Path == lastAppliedConfigPath || strings . HasPrefix ( op . Path , quackAnnotationPrefix ) {
171173 continue
172174 }
173175 allowedOps = append (allowedOps , op )
@@ -181,21 +183,28 @@ func createPatch(old []byte, new []byte) ([]byte, error) {
181183}
182184
183185func getTemplateInput (data []byte ) ([]byte , error ) {
184- // Remove annotations from input template
185- removeAnnotations := []byte (`[
186- {"op": "remove", "path": "/metadata/annotations"}
187- ]` )
188- patch , err := mergepatch .DecodePatch (removeAnnotations )
186+ // Fetch object meta into object
187+ objectMeta , err := getObjectMeta (data )
189188 if err != nil {
190- return [] byte {} , fmt .Errorf ("unable to decode remove annotation patch : %v" , err )
189+ return nil , fmt .Errorf ("error reading object metadata : %v" , err )
191190 }
192191
193- // Apply patch to remove annotations
194- templateInput , err := patch .Apply (data )
195- if err != nil {
196- return []byte {}, fmt .Errorf ("unable to apply remove annotation patch: %v" , err )
192+ var patchedData []byte
193+ for annotation := range objectMeta .Annotations {
194+ if strings .HasPrefix (annotation , "quack.pusher.com" ) {
195+ // Remove annotations from input template
196+ escapedAnnotation := strings .Replace (annotation , "/" , "~1" , - 1 )
197+ patch := []byte (fmt .Sprintf (`[
198+ {"op": "remove", "path": "/metadata/annotations/%s"}
199+ ]` , escapedAnnotation ))
200+ patchedData , err = applyPatch (data , patch )
201+ if err != nil {
202+ return nil , fmt .Errorf ("error removing annotation %s: %v" , annotation , err )
203+ }
204+ }
197205 }
198- return templateInput , nil
206+
207+ return patchedData , nil
199208}
200209
201210func requestHasAnnotation (requiredAnnotation string , raw []byte ) (bool , error ) {
@@ -204,23 +213,45 @@ func requestHasAnnotation(requiredAnnotation string, raw []byte) (bool, error) {
204213 }
205214
206215 // Fetch object meta into object
216+ objectMeta , err := getObjectMeta (raw )
217+ if err != nil {
218+ return false , fmt .Errorf ("error reading object metadata: %v" , err )
219+ }
220+
221+ glog .V (6 ).Infof ("Requested Object Annotations: %v" , objectMeta .Annotations )
222+
223+ // Check required annotation exists in struct
224+ if _ , ok := objectMeta .Annotations [requiredAnnotation ]; ok {
225+ return true , nil
226+ }
227+ return false , nil
228+ }
229+
230+ func getObjectMeta (raw []byte ) (metav1.ObjectMeta , error ) {
207231 requestMeta := struct {
208232 metav1.ObjectMeta `json:"metadata"`
209233 }{
210234 ObjectMeta : metav1.ObjectMeta {},
211235 }
212236 err := json .Unmarshal (raw , & requestMeta )
213237 if err != nil {
214- return false , fmt .Errorf ("failed ot unmarshal input: %v" , err )
238+ return metav1. ObjectMeta {} , fmt .Errorf ("failed to unmarshal input: %v" , err )
215239 }
240+ return requestMeta .ObjectMeta , nil
241+ }
216242
217- glog .V (6 ).Infof ("Requested Object Annotions: %v" , requestMeta .ObjectMeta .Annotations )
243+ func applyPatch (data , patchBytes []byte ) ([]byte , error ) {
244+ patch , err := mergepatch .DecodePatch (patchBytes )
245+ if err != nil {
246+ return nil , fmt .Errorf ("unable to decode patch: %v" , err )
247+ }
218248
219- // Check required annotation exists in struct
220- if _ , ok := requestMeta .ObjectMeta .Annotations [requiredAnnotation ]; ok {
221- return true , nil
249+ // Apply patch to remove annotations
250+ patchedData , err := patch .Apply (data )
251+ if err != nil {
252+ return nil , fmt .Errorf ("unable to apply patch: %v" , err )
222253 }
223- return false , nil
254+ return patchedData , nil
224255}
225256
226257type delimiters struct {
@@ -240,7 +271,7 @@ func getDelims(raw []byte) (delimiters, error) {
240271 return delimiters {}, fmt .Errorf ("failed ot unmarshal input: %v" , err )
241272 }
242273
243- glog .V (6 ).Infof ("Requested Object Annotions : %v" , requestMeta .ObjectMeta .Annotations )
274+ glog .V (6 ).Infof ("Requested Object Annotations : %v" , requestMeta .ObjectMeta .Annotations )
244275
245276 left , lOk := requestMeta .ObjectMeta .Annotations [leftDelimAnnotation ]
246277 right , rOk := requestMeta .ObjectMeta .Annotations [rightDelimAnnotation ]
0 commit comments