mirror of
https://github.com/containous/traefik.git
synced 2025-01-25 06:03:49 +03:00
fix: list parsing.
This commit is contained in:
parent
b1ea36793b
commit
b60edd9ee9
@ -33,6 +33,7 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||||||
"GetBool": p.getBool,
|
"GetBool": p.getBool,
|
||||||
"GetInt": p.getInt,
|
"GetInt": p.getInt,
|
||||||
"GetInt64": p.getInt64,
|
"GetInt64": p.getInt64,
|
||||||
|
"GetList": p.getList,
|
||||||
"SplitGet": p.splitGet,
|
"SplitGet": p.splitGet,
|
||||||
"Last": p.last,
|
"Last": p.last,
|
||||||
"Has": p.has,
|
"Has": p.has,
|
||||||
@ -44,9 +45,9 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||||||
"getPriority": p.getFuncInt(pathFrontendPriority, 0),
|
"getPriority": p.getFuncInt(pathFrontendPriority, 0),
|
||||||
"getPassHostHeader": p.getFuncBool(pathFrontendPassHostHeader, true),
|
"getPassHostHeader": p.getFuncBool(pathFrontendPassHostHeader, true),
|
||||||
"getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert),
|
"getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||||
"getEntryPoints": p.getFuncSlice(pathFrontendEntryPoints),
|
"getEntryPoints": p.getFuncList(pathFrontendEntryPoints),
|
||||||
"getWhitelistSourceRange": p.getFuncSlice(pathFrontendWhiteListSourceRange),
|
"getWhitelistSourceRange": p.getFuncList(pathFrontendWhiteListSourceRange),
|
||||||
"getBasicAuth": p.getFuncSlice(pathFrontendBasicAuth),
|
"getBasicAuth": p.getFuncList(pathFrontendBasicAuth),
|
||||||
"getRoutes": p.getRoutes,
|
"getRoutes": p.getRoutes,
|
||||||
"getRedirect": p.getRedirect,
|
"getRedirect": p.getRedirect,
|
||||||
"getErrorPages": p.getErrorPages,
|
"getErrorPages": p.getErrorPages,
|
||||||
@ -137,7 +138,7 @@ func (p *Provider) getErrorPages(rootPath string) map[string]*types.ErrorPage {
|
|||||||
errorPages[pageName] = &types.ErrorPage{
|
errorPages[pageName] = &types.ErrorPage{
|
||||||
Backend: p.get("", pathPage, pathFrontendErrorPagesBackend),
|
Backend: p.get("", pathPage, pathFrontendErrorPagesBackend),
|
||||||
Query: p.get("", pathPage, pathFrontendErrorPagesQuery),
|
Query: p.get("", pathPage, pathFrontendErrorPagesQuery),
|
||||||
Status: p.splitGet(pathPage, pathFrontendErrorPagesStatus),
|
Status: p.getList(pathPage, pathFrontendErrorPagesStatus),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +188,8 @@ func (p *Provider) getHeaders(rootPath string) *types.Headers {
|
|||||||
CustomRequestHeaders: p.getMap(rootPath, pathFrontendCustomRequestHeaders),
|
CustomRequestHeaders: p.getMap(rootPath, pathFrontendCustomRequestHeaders),
|
||||||
CustomResponseHeaders: p.getMap(rootPath, pathFrontendCustomResponseHeaders),
|
CustomResponseHeaders: p.getMap(rootPath, pathFrontendCustomResponseHeaders),
|
||||||
SSLProxyHeaders: p.getMap(rootPath, pathFrontendSSLProxyHeaders),
|
SSLProxyHeaders: p.getMap(rootPath, pathFrontendSSLProxyHeaders),
|
||||||
AllowedHosts: p.splitGet("", rootPath, pathFrontendAllowedHosts),
|
AllowedHosts: p.getList("", rootPath, pathFrontendAllowedHosts),
|
||||||
HostsProxyHeaders: p.splitGet(rootPath, pathFrontendHostsProxyHeaders),
|
HostsProxyHeaders: p.getList(rootPath, pathFrontendHostsProxyHeaders),
|
||||||
SSLRedirect: p.getBool(false, rootPath, pathFrontendSSLRedirect),
|
SSLRedirect: p.getBool(false, rootPath, pathFrontendSSLRedirect),
|
||||||
SSLTemporaryRedirect: p.getBool(false, rootPath, pathFrontendSSLTemporaryRedirect),
|
SSLTemporaryRedirect: p.getBool(false, rootPath, pathFrontendSSLTemporaryRedirect),
|
||||||
SSLHost: p.get("", rootPath, pathFrontendSSLHost),
|
SSLHost: p.get("", rootPath, pathFrontendSSLHost),
|
||||||
@ -284,7 +285,7 @@ func (p *Provider) getTLSConfigurations(prefix string) []*tls.Configuration {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
entryPoints := p.splitGet(tlsConfPath, pathTLSConfigurationEntryPoints)
|
entryPoints := p.getList(tlsConfPath, pathTLSConfigurationEntryPoints)
|
||||||
if len(entryPoints) == 0 {
|
if len(entryPoints) == 0 {
|
||||||
log.Warnf("Invalid TLS configuration (no entry points): %s", tlsConfPath)
|
log.Warnf("Invalid TLS configuration (no entry points): %s", tlsConfPath)
|
||||||
continue
|
continue
|
||||||
@ -406,9 +407,9 @@ func (p *Provider) getFuncInt(key string, defaultValue int) func(rootPath string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) getFuncSlice(key string) func(rootPath string) []string {
|
func (p *Provider) getFuncList(key string) func(rootPath string) []string {
|
||||||
return func(rootPath string) []string {
|
return func(rootPath string) []string {
|
||||||
return p.splitGet(rootPath, key)
|
return p.getList(rootPath, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,6 +502,34 @@ func (p *Provider) list(keyParts ...string) []string {
|
|||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getList(keyParts ...string) []string {
|
||||||
|
values := p.splitGet(keyParts...)
|
||||||
|
if len(values) > 0 {
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.getSlice(keyParts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get sub keys. ex: foo/0, foo/1, foo/2
|
||||||
|
func (p *Provider) getSlice(keyParts ...string) []string {
|
||||||
|
baseKey := strings.Join(keyParts, "")
|
||||||
|
if !strings.HasSuffix(baseKey, "/") {
|
||||||
|
baseKey += "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
listKeys := p.list(baseKey)
|
||||||
|
|
||||||
|
var values []string
|
||||||
|
for _, entryKey := range listKeys {
|
||||||
|
val := p.get("", entryKey)
|
||||||
|
if len(val) > 0 {
|
||||||
|
values = append(values, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) splitGet(keyParts ...string) []string {
|
func (p *Provider) splitGet(keyParts ...string) []string {
|
||||||
value := p.get("", keyParts...)
|
value := p.get("", keyParts...)
|
||||||
|
|
||||||
|
@ -562,6 +562,158 @@ func TestProviderSplitGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProviderGetList(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
kvPairs []*store.KVPair
|
||||||
|
kvError error
|
||||||
|
keyParts []string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "comma separated",
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("entrypoints", "courgette, carotte, tomate, aubergine"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: []string{"courgette", "carotte", "tomate", "aubergine"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "multiple entries",
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("entrypoints/0", "courgette"),
|
||||||
|
withPair("entrypoints/1", "carotte"),
|
||||||
|
withPair("entrypoints/2", "tomate"),
|
||||||
|
withPair("entrypoints/3", "aubergine"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: []string{"courgette", "carotte", "tomate", "aubergine"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "when empty value",
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("bar", ""),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "when not existing key",
|
||||||
|
kvPairs: nil,
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "when KV error",
|
||||||
|
kvError: store.ErrNotReachable,
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("bar", ""),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
p := &Provider{
|
||||||
|
kvClient: newKvClientMock(test.kvPairs, test.kvError),
|
||||||
|
}
|
||||||
|
|
||||||
|
values := p.getList(test.keyParts...)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expected, values, "key: %v", test.keyParts)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProviderGetSlice(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
kvPairs []*store.KVPair
|
||||||
|
kvError error
|
||||||
|
keyParts []string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "multiple entries",
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("entrypoints/0", "courgette"),
|
||||||
|
withPair("entrypoints/1", "carotte"),
|
||||||
|
withPair("entrypoints/2", "tomate"),
|
||||||
|
withPair("entrypoints/3", "aubergine"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: []string{"courgette", "carotte", "tomate", "aubergine"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "comma separated",
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("entrypoints", "courgette, carotte, tomate, aubergine"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "when empty value",
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("bar", ""),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "when not existing key",
|
||||||
|
kvPairs: nil,
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "when KV error",
|
||||||
|
kvError: store.ErrNotReachable,
|
||||||
|
kvPairs: filler("traefik",
|
||||||
|
frontend("foo",
|
||||||
|
withPair("bar", ""),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyParts: []string{"traefik/frontends/foo/entrypoints"},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
p := &Provider{
|
||||||
|
kvClient: newKvClientMock(test.kvPairs, test.kvError),
|
||||||
|
}
|
||||||
|
|
||||||
|
values := p.getSlice(test.keyParts...)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expected, values, "key: %v", test.keyParts)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestProviderGetBool(t *testing.T) {
|
func TestProviderGetBool(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user