github.com/jpedro/terraform@v0.11.12-beta1/helper/variables/merge.go (about) 1 package variables 2 3 // Merge merges raw variable values b into a. 4 // 5 // The parameters given here should be the full map of set variables, such 6 // as those created by Flag and FlagFile. 7 // 8 // The merge behavior is to override the top-level key except for map 9 // types. Map types are merged together by key. Any other types are overwritten: 10 // primitives and lists. 11 // 12 // This returns the resulting map. This merges into a but if a is nil a new 13 // map will be allocated. A non-nil "a" value is returned regardless. 14 func Merge(a, b map[string]interface{}) map[string]interface{} { 15 if a == nil { 16 a = map[string]interface{}{} 17 } 18 19 for k, raw := range b { 20 switch v := raw.(type) { 21 case map[string]interface{}: 22 // For maps, we do a deep merge. If the value in the original 23 // map (a) is not a map, we just overwrite. For invalid types 24 // they're caught later in the validation step in Terraform. 25 26 // If there is no value set, just set it 27 rawA, ok := a[k] 28 if !ok { 29 a[k] = v 30 continue 31 } 32 33 // If the value is not a map, just set it 34 mapA, ok := rawA.(map[string]interface{}) 35 if !ok { 36 a[k] = v 37 continue 38 } 39 40 // Go over the values in the map. If we're setting a raw value, 41 // then override. If we're setting a nested map, then recurse. 42 for k, v := range v { 43 // If the value isn't a map, then there is nothing to merge 44 // further so we just set it. 45 mv, ok := v.(map[string]interface{}) 46 if !ok { 47 mapA[k] = v 48 continue 49 } 50 51 switch av := mapA[k].(type) { 52 case map[string]interface{}: 53 mapA[k] = Merge(av, mv) 54 default: 55 // Unset or non-map, just set it 56 mapA[k] = mv 57 } 58 } 59 default: 60 // Any other type we just set directly 61 a[k] = v 62 } 63 } 64 65 return a 66 }