@@ -42,6 +42,7 @@ type WalkTemplatesOptions struct {
42
42
failForUnknownTypes bool
43
43
patchFormat runtimehooksv1.PatchType
44
44
// TODO: add the possibility to set patchFormat for single patches only, eg. via a func(requestItem) format.
45
+ KeepEmptyFields bool
45
46
}
46
47
47
48
// newWalkTemplatesOptions returns a WalkTemplatesOptions with default values.
@@ -61,6 +62,14 @@ func (f FailForUnknownTypes) ApplyToWalkTemplates(in *WalkTemplatesOptions) {
61
62
in .failForUnknownTypes = true
62
63
}
63
64
65
+ // KeepEmptyFields defines if WalkTemplates should keep empty fields which is old behavior
66
+ type KeepEmptyFields struct {}
67
+
68
+ // ApplyToWalkTemplates applies this configuration to the given WalkTemplatesOptions.
69
+ func (f KeepEmptyFields ) ApplyToWalkTemplates (in * WalkTemplatesOptions ) {
70
+ in .KeepEmptyFields = true
71
+ }
72
+
64
73
// PatchFormat defines the patch format that WalkTemplates should generate.
65
74
// If not set, JSONPatchType will be used.
66
75
type PatchFormat struct {
@@ -147,14 +156,22 @@ func WalkTemplates(ctx context.Context, decoder runtime.Decoder, req *runtimehoo
147
156
var patch []byte
148
157
switch options .patchFormat {
149
158
case runtimehooksv1 .JSONPatchType :
150
- patch , err = createJSONPatch (requestItem .Object .Raw , modified )
159
+ if options .KeepEmptyFields {
160
+ patch , err = createJSONPatchKeepEmptyFields (original , modified )
161
+ } else {
162
+ patch , err = createJSONPatch (requestItem .Object .Raw , modified )
163
+ }
151
164
if err != nil {
152
165
resp .Status = runtimehooksv1 .ResponseStatusFailure
153
166
resp .Message = err .Error ()
154
167
return
155
168
}
156
169
case runtimehooksv1 .JSONMergePatchType :
157
- patch , err = createJSONMergePatch (requestItem .Object .Raw , modified )
170
+ if options .KeepEmptyFields {
171
+ patch , err = createJSONMergePatchKeepEmptyFields (original , modified )
172
+ } else {
173
+ patch , err = createJSONMergePatch (requestItem .Object .Raw , modified )
174
+ }
158
175
if err != nil {
159
176
resp .Status = runtimehooksv1 .ResponseStatusFailure
160
177
resp .Message = err .Error ()
@@ -207,3 +224,48 @@ func createJSONMergePatch(marshalledOriginal []byte, modified runtime.Object) ([
207
224
208
225
return patch , nil
209
226
}
227
+
228
+ // createJSONPatchKeepEmptyFields creates a RFC 6902 JSON patch from the original and the modified object.
229
+ func createJSONPatchKeepEmptyFields (original , modified runtime.Object ) ([]byte , error ) {
230
+ marshalledOriginal , err := json .Marshal (original )
231
+ if err != nil {
232
+ return nil , errors .Errorf ("failed to marshal original object: %v" , err )
233
+ }
234
+
235
+ marshalledModified , err := json .Marshal (modified )
236
+ if err != nil {
237
+ return nil , errors .Errorf ("failed to marshal modified object: %v" , err )
238
+ }
239
+
240
+ patch , err := jsonpatch .CreatePatch (marshalledOriginal , marshalledModified )
241
+ if err != nil {
242
+ return nil , errors .Errorf ("failed to create patch: %v" , err )
243
+ }
244
+
245
+ patchBytes , err := json .Marshal (patch )
246
+ if err != nil {
247
+ return nil , errors .Errorf ("failed to marshal patch: %v" , err )
248
+ }
249
+
250
+ return patchBytes , nil
251
+ }
252
+
253
+ // createJSONMergePatchKeepEmptyFields creates a RFC 7396 JSON merge patch from the original and the modified object.
254
+ func createJSONMergePatchKeepEmptyFields (original , modified runtime.Object ) ([]byte , error ) {
255
+ marshalledOriginal , err := json .Marshal (original )
256
+ if err != nil {
257
+ return nil , errors .Errorf ("failed to marshal original object: %v" , err )
258
+ }
259
+
260
+ marshalledModified , err := json .Marshal (modified )
261
+ if err != nil {
262
+ return nil , errors .Errorf ("failed to marshal modified object: %v" , err )
263
+ }
264
+
265
+ patch , err := mergepatch .CreateMergePatch (marshalledOriginal , marshalledModified )
266
+ if err != nil {
267
+ return nil , errors .Errorf ("failed to create patch: %v" , err )
268
+ }
269
+
270
+ return patch , nil
271
+ }
0 commit comments