Merge pull request #3746 from hashicorp/node-meta-merge
Changes maps to merge vs. overwrite when processing configs.
This commit is contained in:
commit
3dc3ba8d37
|
@ -40,7 +40,8 @@ import (
|
||||||
//
|
//
|
||||||
// The config sources are merged sequentially and later values
|
// The config sources are merged sequentially and later values
|
||||||
// overwrite previously set values. Slice values are merged by
|
// overwrite previously set values. Slice values are merged by
|
||||||
// concatenating the two slices.
|
// concatenating the two slices. Map values are merged by over-
|
||||||
|
// laying the later maps on top of earlier ones.
|
||||||
//
|
//
|
||||||
// Then call Validate() to perform the semantic validation to ensure
|
// Then call Validate() to perform the semantic validation to ensure
|
||||||
// that the configuration is ready to be used.
|
// that the configuration is ready to be used.
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
// * only values of type struct, slice, map and pointer to simple types are allowed. Other types panic.
|
// * only values of type struct, slice, map and pointer to simple types are allowed. Other types panic.
|
||||||
// * when merging two structs the result is the recursive merge of all fields according to the rules below
|
// * when merging two structs the result is the recursive merge of all fields according to the rules below
|
||||||
// * when merging two slices the result is the second slice appended to the first
|
// * when merging two slices the result is the second slice appended to the first
|
||||||
// * when merging two maps the result is the second map if it is not empty, otherwise the first
|
// * when merging two maps the result is the second map overlaid on the first
|
||||||
// * when merging two pointer values the result is the second value if it is not nil, otherwise the first
|
// * when merging two pointer values the result is the second value if it is not nil, otherwise the first
|
||||||
func Merge(files ...Config) Config {
|
func Merge(files ...Config) Config {
|
||||||
var a Config
|
var a Config
|
||||||
|
@ -28,10 +28,16 @@ func merge(a, b interface{}) interface{} {
|
||||||
func mergeValue(a, b reflect.Value) reflect.Value {
|
func mergeValue(a, b reflect.Value) reflect.Value {
|
||||||
switch a.Kind() {
|
switch a.Kind() {
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
if b.Len() > 0 {
|
r := reflect.MakeMap(a.Type())
|
||||||
return b
|
for _, k := range a.MapKeys() {
|
||||||
|
v := a.MapIndex(k)
|
||||||
|
r.SetMapIndex(k, v)
|
||||||
}
|
}
|
||||||
return a
|
for _, k := range b.MapKeys() {
|
||||||
|
v := b.MapIndex(k)
|
||||||
|
r.SetMapIndex(k, v)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if !b.IsNil() {
|
if !b.IsNil() {
|
||||||
|
|
|
@ -26,6 +26,7 @@ func TestMerge(t *testing.T) {
|
||||||
{StartJoinAddrsLAN: []string{"b"}},
|
{StartJoinAddrsLAN: []string{"b"}},
|
||||||
{NodeMeta: map[string]string{"a": "b"}},
|
{NodeMeta: map[string]string{"a": "b"}},
|
||||||
{NodeMeta: map[string]string{"c": "d"}},
|
{NodeMeta: map[string]string{"c": "d"}},
|
||||||
|
{NodeMeta: map[string]string{"c": "e"}},
|
||||||
{Ports: Ports{DNS: pInt(1)}},
|
{Ports: Ports{DNS: pInt(1)}},
|
||||||
{Ports: Ports{DNS: pInt(2), HTTP: pInt(3)}},
|
{Ports: Ports{DNS: pInt(2), HTTP: pInt(3)}},
|
||||||
},
|
},
|
||||||
|
@ -34,8 +35,11 @@ func TestMerge(t *testing.T) {
|
||||||
RaftProtocol: pInt(2),
|
RaftProtocol: pInt(2),
|
||||||
ServerMode: pBool(true),
|
ServerMode: pBool(true),
|
||||||
StartJoinAddrsLAN: []string{"a", "b"},
|
StartJoinAddrsLAN: []string{"a", "b"},
|
||||||
NodeMeta: map[string]string{"c": "d"},
|
NodeMeta: map[string]string{
|
||||||
Ports: Ports{DNS: pInt(2), HTTP: pInt(3)},
|
"a": "b",
|
||||||
|
"c": "e",
|
||||||
|
},
|
||||||
|
Ports: Ports{DNS: pInt(2), HTTP: pInt(3)},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1115,7 +1115,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
"bootstrap_expect": 0,
|
"bootstrap_expect": 0,
|
||||||
"datacenter":"b",
|
"datacenter":"b",
|
||||||
"start_join": ["c", "d"],
|
"start_join": ["c", "d"],
|
||||||
"node_meta": {"c":"d"}
|
"node_meta": {"a":"c"}
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
hcl: []string{
|
hcl: []string{
|
||||||
|
@ -1131,7 +1131,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
bootstrap_expect = 0
|
bootstrap_expect = 0
|
||||||
datacenter = "b"
|
datacenter = "b"
|
||||||
start_join = ["c", "d"]
|
start_join = ["c", "d"]
|
||||||
node_meta = { "c" = "d" }
|
node_meta = { "a" = "c" }
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
patch: func(rt *RuntimeConfig) {
|
patch: func(rt *RuntimeConfig) {
|
||||||
|
@ -1139,7 +1139,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
rt.BootstrapExpect = 0
|
rt.BootstrapExpect = 0
|
||||||
rt.Datacenter = "b"
|
rt.Datacenter = "b"
|
||||||
rt.StartJoinAddrsLAN = []string{"a", "b", "c", "d"}
|
rt.StartJoinAddrsLAN = []string{"a", "b", "c", "d"}
|
||||||
rt.NodeMeta = map[string]string{"c": "d"}
|
rt.NodeMeta = map[string]string{"a": "c"}
|
||||||
rt.DataDir = dataDir
|
rt.DataDir = dataDir
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1181,7 +1181,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
`-datacenter=b`,
|
`-datacenter=b`,
|
||||||
`-data-dir=` + dataDir,
|
`-data-dir=` + dataDir,
|
||||||
`-join`, `c`, `-join=d`,
|
`-join`, `c`, `-join=d`,
|
||||||
`-node-meta=c:d`,
|
`-node-meta=a:c`,
|
||||||
`-recursor`, `1.2.3.6`, `-recursor=5.6.7.10`,
|
`-recursor`, `1.2.3.6`, `-recursor=5.6.7.10`,
|
||||||
`-serf-lan-bind=3.3.3.3`,
|
`-serf-lan-bind=3.3.3.3`,
|
||||||
`-serf-wan-bind=4.4.4.4`,
|
`-serf-wan-bind=4.4.4.4`,
|
||||||
|
@ -1194,7 +1194,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
rt.SerfAdvertiseAddrWAN = tcpAddr("2.2.2.2:8302")
|
rt.SerfAdvertiseAddrWAN = tcpAddr("2.2.2.2:8302")
|
||||||
rt.Datacenter = "b"
|
rt.Datacenter = "b"
|
||||||
rt.DNSRecursors = []string{"1.2.3.6", "5.6.7.10", "1.2.3.5", "5.6.7.9"}
|
rt.DNSRecursors = []string{"1.2.3.6", "5.6.7.10", "1.2.3.5", "5.6.7.9"}
|
||||||
rt.NodeMeta = map[string]string{"c": "d"}
|
rt.NodeMeta = map[string]string{"a": "c"}
|
||||||
rt.SerfBindAddrLAN = tcpAddr("3.3.3.3:8301")
|
rt.SerfBindAddrLAN = tcpAddr("3.3.3.3:8301")
|
||||||
rt.SerfBindAddrWAN = tcpAddr("4.4.4.4:8302")
|
rt.SerfBindAddrWAN = tcpAddr("4.4.4.4:8302")
|
||||||
rt.StartJoinAddrsLAN = []string{"c", "d", "a", "b"}
|
rt.StartJoinAddrsLAN = []string{"c", "d", "a", "b"}
|
||||||
|
|
Loading…
Reference in New Issue