github.com/verrazzano/verrazzano@v1.7.0/pkg/yaml/strategic_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 "errors" 8 "k8s.io/apimachinery/pkg/util/strategicpatch" 9 "os" 10 "path/filepath" 11 "sigs.k8s.io/yaml" 12 "strings" 13 ) 14 15 type PatchStrategy interface{} 16 17 type yamlMap struct { 18 yMap map[string]interface{} 19 } 20 21 // StrategicMergeFiles merges the YAML files returns a YAML string. 22 // The first file is overlayed by each subsequent file 23 // The strategy is a JSON annotated structure that represents the YAML structure 24 func StrategicMergeFiles(strategy PatchStrategy, yamlFiles ...string) (string, error) { 25 var yamls []string 26 for _, f := range yamlFiles { 27 yam, err := os.ReadFile(filepath.Join(f)) 28 if err != nil { 29 return "", err 30 } 31 yamls = append(yamls, string(yam)) 32 } 33 return StrategicMerge(strategy, yamls...) 34 } 35 36 // StrategicMerge merges the YAML files returns a YAML string. 37 // The first YAML is overlayed by each subsequent YAML 38 // The strategy is a JSON annotated structure that represents the YAML structure 39 func StrategicMerge(strategy PatchStrategy, yamls ...string) (string, error) { 40 if len(yamls) == 0 { 41 return "", errors.New("At least 1 YAML file is required") 42 } 43 if len(yamls) == 1 { 44 return yamls[0], nil 45 } 46 47 var mergedJSON []byte 48 for _, yam := range yamls { 49 // First time through create the base JSON 50 overlayYAML := strings.TrimSpace(yam) 51 overlayJSON, err := yaml.YAMLToJSON([]byte(overlayYAML)) 52 if err != nil { 53 return "", err 54 } 55 if len(mergedJSON) == 0 { 56 mergedJSON = overlayJSON 57 continue 58 } 59 mergedJSON, err = strategicpatch.StrategicMergePatch(mergedJSON, overlayJSON, strategy) 60 if err != nil { 61 return "", err 62 } 63 } 64 mergedYaml, err := yaml.JSONToYAML(mergedJSON) 65 if err != nil { 66 return "", err 67 } 68 return strings.TrimSpace(string(mergedYaml)), nil 69 }