Skip to content

Commit 9e762bd

Browse files
Merge pull request #14 from kaleido-io/arrays
Better handling of subarray defaults
2 parents 28b2841 + 31fea95 commit 9e762bd

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

pkg/config/config.go

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,9 @@ func GetKnownKeys() []string {
244244

245245
// configSection is the main config structure passed to plugins, and used for root to wrap viper
246246
type configSection struct {
247-
prefix string
248-
parent sectionParent
247+
prefix string
248+
parent sectionParent
249+
arrayEntry bool
249250
}
250251

251252
// configArray is a point in the config that supports an array
@@ -301,12 +302,21 @@ func (c *configArray) SubSection(name string) Section {
301302
return cp
302303
}
303304

304-
func findArrayParent(c *configSection) *configArray {
305-
switch p := c.parent.(type) {
305+
// If any parent is an array entry, retrieve fully-qualified defaults via its array parent
306+
func getArrayEntryDefaults(p sectionParent) map[string][]interface{} {
307+
switch c := p.(type) {
306308
case *configArray:
307-
return p
309+
return getArrayEntryDefaults(c.parent)
308310
case *configSection:
309-
return findArrayParent(p)
311+
if !c.arrayEntry {
312+
return getArrayEntryDefaults(c.parent)
313+
}
314+
arrayParent := c.parent.(*configArray)
315+
defaults := make(map[string][]interface{})
316+
for k, v := range arrayParent.defaults {
317+
defaults[c.prefix+"."+k] = v
318+
}
319+
return defaults
310320
default:
311321
return nil
312322
}
@@ -318,14 +328,12 @@ func (c *configSection) SubArray(name string) ArraySection {
318328
parent: c,
319329
defaults: make(map[string][]interface{}),
320330
}
321-
// If a parent array already has defaults for this subtree, copy them here (for later use in ArrayEntry)
322-
parentArray := findArrayParent(c)
323-
if parentArray != nil {
324-
prefix := a.base + "[]."
325-
for key, val := range parentArray.defaults {
326-
if strings.HasPrefix(key, prefix) {
327-
a.defaults[strings.TrimPrefix(key, prefix)] = val
328-
}
331+
// Get defaults from any enclosing array entry, and copy over any applicable to this subtree
332+
// This is necessary to propagate known keys for arrays within arrays
333+
prefix := a.base + "[]."
334+
for key, val := range getArrayEntryDefaults(c) {
335+
if strings.HasPrefix(key, prefix) {
336+
a.defaults[strings.TrimPrefix(key, prefix)] = val
329337
}
330338
}
331339
return a
@@ -343,8 +351,9 @@ func (c *configArray) ArraySize() int {
343351
// ArrayEntry must only be called after the config has been loaded
344352
func (c *configArray) ArrayEntry(i int) Section {
345353
cp := &configSection{
346-
prefix: keyName(c.base, fmt.Sprintf("%d", i)),
347-
parent: c,
354+
prefix: keyName(c.base, fmt.Sprintf("%d", i)),
355+
parent: c,
356+
arrayEntry: true,
348357
}
349358
for knownKey, defValue := range c.defaults {
350359
cp.AddKnownKey(knownKey, defValue...)
@@ -391,7 +400,9 @@ func (c *configSection) AddKnownKey(k string, defValue ...interface{}) {
391400
func (c *configArray) AddChild(k string, defValue ...interface{}) {
392401
// When a child is added anywhere below this array, add it to the defaults map
393402
prefix := c.base + "[]."
394-
c.defaults[strings.TrimPrefix(k, prefix)] = defValue
403+
if strings.HasPrefix(k, prefix) {
404+
c.defaults[strings.TrimPrefix(k, prefix)] = defValue
405+
}
395406

396407
// Also bubble it upwards
397408
if c.parent != nil {

pkg/config/config_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func TestArrayOfPlugins(t *testing.T) {
155155
fft.AddKnownKey("url")
156156
fft.SubSection("proxy").AddKnownKey("url")
157157
headers := fft.SubArray("headers")
158-
headers.AddKnownKey("name")
158+
headers.AddKnownKey("name", "defname")
159159
viper.SetConfigType("yaml")
160160
err := viper.ReadConfig(strings.NewReader(`
161161
plugins:
@@ -168,7 +168,7 @@ plugins:
168168
url: http://proxy
169169
headers:
170170
- name: header1
171-
- name: header2
171+
- badkey: bad
172172
`))
173173
assert.NoError(t, err)
174174
assert.Equal(t, 1, tokPlugins.ArraySize())
@@ -183,7 +183,7 @@ plugins:
183183
bobheaders := bobfft.SubArray("headers")
184184
assert.Equal(t, 2, bobheaders.ArraySize())
185185
assert.Equal(t, "header1", bobheaders.ArrayEntry(0).GetString("name"))
186-
assert.Equal(t, "header2", bobheaders.ArrayEntry(1).GetString("name"))
186+
assert.Equal(t, "defname", bobheaders.ArrayEntry(1).GetString("name"))
187187
}
188188

189189
func TestMapOfAdminOverridePlugins(t *testing.T) {

0 commit comments

Comments
 (0)