How to restrict patch from patching some specific key?
Problem:
We want to patch an object but we don't want to allow to modify some fields of the object.
Solution:
Use mergepatch.PreconditionFunc.
What is PreconditionFunc?
PreconditionFunc asserts that an incompatible change is not present within a patch. It takes generated patch and return if either patch is allowed(true) or forbidden(false) based on key's existent on patch.
typePreconditionFuncfunc(interface{}) bool
mergepatch library has two helper function that return PreconditionFunc
// RequireKeyUnchanged returns a precondition function that fails if the provided key// is present in the patch (indicating that its value has changed).funcRequireKeyUnchanged(key string) PreconditionFunc {returnfunc(patch interface{}) bool { patchMap, ok := patch.(map[string]interface{})if!ok {returntrue }// The presence of key means that its value has been changed, so the test fails. _, ok = patchMap[key]return!ok }}
and
// RequireMetadataKeyUnchanged creates a precondition function that fails// if the metadata.key is present in the patch (indicating its value// has changed).funcRequireMetadataKeyUnchanged(key string) PreconditionFunc {returnfunc(patch interface{}) bool { patchMap, ok := patch.(map[string]interface{})if!ok {returntrue } patchMap1, ok := patchMap["metadata"]if!ok {returntrue } patchMap2, ok := patchMap1.(map[string]interface{})if!ok {returntrue } _, ok = patchMap2[key]return!ok }}