Allows multi-level KV prefixes

This commit is contained in:
Никита Тимофеев 2020-08-11 18:42:05 +03:00 committed by GitHub
parent de458b7357
commit 449afea4fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 38 deletions

View file

@ -20,13 +20,13 @@ func DecodeToNode(pairs []*store.KVPair, rootName string, filters ...string) (*p
var node *parser.Node var node *parser.Node
for i, pair := range sortedPairs { for i, pair := range sortedPairs {
split := strings.FieldsFunc(pair.Key, func(c rune) bool { return c == '/' }) if !strings.HasPrefix(pair.Key, rootName+"/") {
return nil, fmt.Errorf("invalid label root %s", rootName)
if split[0] != rootName {
return nil, fmt.Errorf("invalid label root %s", split[0])
} }
var parts []string split := strings.Split(pair.Key[len(rootName)+1:], "/")
parts := []string{rootName}
for _, fragment := range split { for _, fragment := range split {
if exp.MatchString(fragment) { if exp.MatchString(fragment) {
parts = append(parts, "["+fragment+"]") parts = append(parts, "["+fragment+"]")

View file

@ -8,42 +8,93 @@ import (
) )
func TestDecode(t *testing.T) { func TestDecode(t *testing.T) {
pairs := mapToPairs(map[string]string{ testCases := []struct {
"traefik/fielda": "bar", desc string
"traefik/fieldb": "1", rootName string
"traefik/fieldc": "true", pairs map[string]string
"traefik/fieldd/0": "one", expected *sample
"traefik/fieldd/1": "two", }{
"traefik/fielde": "", {
"traefik/fieldf/Test1": "A", desc: "simple case",
"traefik/fieldf/Test2": "B", rootName: "traefik",
"traefik/fieldg/0/name": "A", pairs: map[string]string{
"traefik/fieldg/1/name": "B", "traefik/fielda": "bar",
}) "traefik/fieldb": "1",
"traefik/fieldc": "true",
element := &sample{} "traefik/fieldd/0": "one",
"traefik/fieldd/1": "two",
err := Decode(pairs, element, "traefik") "traefik/fielde": "",
require.NoError(t, err) "traefik/fieldf/Test1": "A",
"traefik/fieldf/Test2": "B",
expected := &sample{ "traefik/fieldg/0/name": "A",
FieldA: "bar", "traefik/fieldg/1/name": "B",
FieldB: 1, },
FieldC: true, expected: &sample{
FieldD: []string{"one", "two"}, FieldA: "bar",
FieldE: &struct { FieldB: 1,
Name string FieldC: true,
}{}, FieldD: []string{"one", "two"},
FieldF: map[string]string{ FieldE: &struct {
"Test1": "A", Name string
"Test2": "B", }{},
FieldF: map[string]string{
"Test1": "A",
"Test2": "B",
},
FieldG: []sub{
{Name: "A"},
{Name: "B"},
},
},
}, },
FieldG: []sub{ {
{Name: "A"}, desc: "multi-level root name",
{Name: "B"}, rootName: "foo/bar/traefik",
pairs: map[string]string{
"foo/bar/traefik/fielda": "bar",
"foo/bar/traefik/fieldb": "2",
"foo/bar/traefik/fieldc": "true",
"foo/bar/traefik/fieldd/0": "one",
"foo/bar/traefik/fieldd/1": "two",
"foo/bar/traefik/fielde": "",
"foo/bar/traefik/fieldf/Test1": "A",
"foo/bar/traefik/fieldf/Test2": "B",
"foo/bar/traefik/fieldg/0/name": "A",
"foo/bar/traefik/fieldg/1/name": "B",
},
expected: &sample{
FieldA: "bar",
FieldB: 2,
FieldC: true,
FieldD: []string{"one", "two"},
FieldE: &struct {
Name string
}{},
FieldF: map[string]string{
"Test1": "A",
"Test2": "B",
},
FieldG: []sub{
{Name: "A"},
{Name: "B"},
},
},
}, },
} }
assert.Equal(t, expected, element)
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
element := &sample{}
err := Decode(mapToPairs(test.pairs), element, test.rootName)
require.NoError(t, err)
assert.Equal(t, test.expected, element)
})
}
} }
type sample struct { type sample struct {