| 306 | } |
| 307 | |
| 308 | func mergeConfigMaps(a, b map[string]interface{}, path string) (_ map[string]interface{}, err error) { |
| 309 | out := make(map[string]interface{}, len(a)) |
| 310 | for k, v := range a { |
| 311 | out[k] = v |
| 312 | } |
| 313 | for k, v := range b { |
| 314 | aVal, aHasKey := a[k] |
| 315 | bVal, bHasKey := b[k] |
| 316 | |
| 317 | _, aIsMap := a[k].(map[string]interface{}) |
| 318 | _, bIsMap := b[k].(map[string]interface{}) |
| 319 | |
| 320 | if aHasKey && aVal == nil && bIsMap { |
| 321 | aIsMap = true |
| 322 | out[k] = make(map[string]interface{}) |
| 323 | } |
| 324 | |
| 325 | if bHasKey && bVal == nil && aIsMap { |
| 326 | bIsMap = true |
| 327 | v = make(map[string]interface{}) |
| 328 | } |
| 329 | |
| 330 | if aHasKey && aIsMap != bIsMap { |
| 331 | return nil, errors.Errorf("conflicting types for %q: %T != %T", path+"."+k, a[k], b[k]) |
| 332 | } |
| 333 | |
| 334 | if v, ok := v.(map[string]interface{}); ok { |
| 335 | if bv, ok := out[k]; ok { |
| 336 | if bv, ok := bv.(map[string]interface{}); ok { |
| 337 | out[k], err = mergeConfigMaps(bv, v, path+"."+k) |
| 338 | if err != nil { |
| 339 | return nil, err |
| 340 | } |
| 341 | continue |
| 342 | } |
| 343 | } |
| 344 | } |
| 345 | out[k] = v |
| 346 | } |
| 347 | return out, nil |
| 348 | } |
| 349 | |
| 350 | func (om *Manager) setConfig(config interface{}) { |
| 351 | om.configPtr.Store(&config) |