github.com/verrazzano/verrazzano@v1.7.0/pkg/yaml/replace_merge.go (about) 1 // Copyright (c) 2021, 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package yaml 5 6 import ( 7 "sigs.k8s.io/yaml" 8 "strings" 9 ) 10 11 // ReplacementMerge merges the YAML files returns a YAML string. 12 // The first YAML is overlayed by each subsequent YAML, lists are replaced 13 func ReplacementMerge(yamls ...string) (string, error) { 14 if len(yamls) == 0 { 15 return "", nil 16 } 17 if len(yamls) == 1 { 18 return yamls[0], nil 19 } 20 var mBase = yamlMap{} 21 for _, yam := range yamls { 22 if len(mBase.yMap) == 0 { 23 if err := yaml.Unmarshal([]byte(yam), &mBase.yMap); err != nil { 24 return "", err 25 } 26 continue 27 } 28 var mOverlay = yamlMap{} 29 if err := yaml.Unmarshal([]byte(yam), &mOverlay.yMap); err != nil { 30 return "", err 31 } 32 if err := MergeMaps(mBase.yMap, mOverlay.yMap); err != nil { 33 return "", err 34 } 35 } 36 b, err := yaml.Marshal(&mBase.yMap) 37 if err != nil { 38 return "", err 39 } 40 return strings.TrimSpace(string(b)), nil 41 } 42 43 // mergeMaps 2 maps where mOverlay overrides mBase 44 func MergeMaps(mBase map[string]interface{}, mOverlay map[string]interface{}) error { 45 for k, vOverlay := range mOverlay { 46 vBase, ok := mBase[k] 47 recursed := false 48 if ok { 49 // Both mBase and mOverlay have this key. If these are nested maps merge them 50 switch tBase := vBase.(type) { 51 case map[string]interface{}: 52 switch tOverlay := vOverlay.(type) { 53 case map[string]interface{}: 54 MergeMaps(tBase, tOverlay) 55 recursed = true 56 } 57 } 58 } 59 // Both values were not maps, put overlay entry into the base map 60 // This might be a new base entry or replaced by the mOverlay value 61 if !recursed { 62 mBase[k] = vOverlay 63 } 64 } 65 return nil 66 }