in pkg/options/patchtmpl/patch.go [288:355]
func objectApplier(scheme *PatcherScheme, patches []*parsedPatch) options.ObjHandler {
return func(obj *unstructured.Unstructured, ref bundle.ComponentReference, _ options.JSONOptions) ([]*unstructured.Unstructured, error) {
objJSON := obj.Object
if obj.GetKind() == "PatchTemplate" {
// Don't process PatchTemplates (possible if includeTemplates is set). In
// other words, it's not allowed to apply patch templates to patch
// templates.
return []*unstructured.Unstructured{obj}, nil
}
// TODO(kashomon): Is there a faster way to convert from JSON-Map to string?
objByt, err := converter.FromObject(objJSON).ToJSON()
if err != nil {
// This would be pretty unlikely
return nil, err
}
deserializer := scheme.Codecs.UniversalDeserializer()
kubeObj, decodeErr := runtime.Decode(deserializer, objByt)
_, isUnstructured := kubeObj.(*unstructured.Unstructured)
strategicWillFail := runtime.IsNotRegisteredError(decodeErr) || isUnstructured
objSchema, objSchemaErr := strategicpatch.NewPatchMetaFromStruct(kubeObj)
for _, pat := range patches {
if !canApplyPatch(pat, obj) {
continue
}
var newObjJSON map[string]interface{}
switch pat.patchType {
case bundle.JSONPatch:
if oByt, err := converter.FromObject(objJSON).ToJSON(); err != nil {
return nil, fmt.Errorf("while converting JSON obj\n%s to bytes: %v", objJSON, err)
} else if pByt, err := converter.FromObject(pat.jsonMap).ToJSON(); err != nil {
return nil, fmt.Errorf("while converting patch JSON obj\n%s to bytes: %v", pat.jsonMap, err)
} else if newObjByt, err := jsonpatch.MergePatch(oByt, pByt); err != nil {
return nil, fmt.Errorf("while applying JSON merge patch\n%s to \n%s: %v", pat.raw, oByt, err)
} else if newObjJSON, err = converter.FromJSON(newObjByt).ToJSONMap(); err != nil {
return nil, fmt.Errorf("while converting bytes\n%s to JSON: %v", newObjByt, err)
}
case bundle.StrategicMergePatch:
if strategicWillFail {
// Strategic merge patch can't handle unstructured.Unstructured or
// unregistered objects, so return an error.
return nil, fmt.Errorf("while converting object %q of kind %q and apiVersion %q: type not registered in scheme", obj.GetName(), obj.GetKind(), obj.GetAPIVersion())
}
if objSchemaErr != nil {
return nil, fmt.Errorf("while getting patch meta from object %s: %v", string(objByt), objSchemaErr)
}
if newObjJSON, err = strategicpatch.StrategicMergeMapPatchUsingLookupPatchMeta(objJSON, pat.jsonMap, objSchema); err != nil {
return nil, fmt.Errorf("while applying strategic merge patch\n%sto \n%s: %v", pat.raw, objJSON, err)
}
default:
return nil, fmt.Errorf("unknown patch type: %s", pat.patchType)
}
objJSON = newObjJSON
}
obj = &unstructured.Unstructured{
Object: runtime.DeepCopyJSON(objJSON),
}
return []*unstructured.Unstructured{obj}, nil
}
}