feat(kv): constants and generic methods.
This commit is contained in:
parent
61ecb4cd18
commit
6573634012
3 changed files with 228 additions and 10 deletions
|
@ -4,19 +4,68 @@ const (
|
|||
pathBackends = "/backends/"
|
||||
pathBackendCircuitBreakerExpression = "/circuitbreaker/expression"
|
||||
pathBackendHealthCheckPath = "/healthcheck/path"
|
||||
pathBackendHealthCheckPort = "/healthcheck/port"
|
||||
pathBackendHealthCheckInterval = "/healthcheck/interval"
|
||||
pathBackendLoadBalancerMethod = "/loadbalancer/method"
|
||||
pathBackendLoadBalancerSticky = "/loadbalancer/sticky"
|
||||
pathBackendLoadBalancerStickiness = "/loadbalancer/stickiness"
|
||||
pathBackendLoadBalancerStickinessCookieName = "/loadbalancer/stickiness/cookiename"
|
||||
pathBackendMaxConnAmount = "/maxconn/amount"
|
||||
pathBackendMaxConnExtractorFunc = "/maxconn/extractorfunc"
|
||||
pathBackendServers = "/servers/"
|
||||
pathBackendServerURL = "/url"
|
||||
pathBackendServerWeight = "/weight"
|
||||
|
||||
pathFrontends = "/frontends/"
|
||||
pathFrontendBackend = "/backend"
|
||||
pathFrontendPriority = "/priority"
|
||||
pathFrontendPassHostHeader = "/passHostHeader"
|
||||
pathFrontendEntryPoints = "/entrypoints"
|
||||
pathFrontends = "/frontends/"
|
||||
pathFrontendBackend = "/backend"
|
||||
pathFrontendPriority = "/priority"
|
||||
pathFrontendPassHostHeader = "/passHostHeader"
|
||||
pathFrontendPassTLSCert = "/passtlscert"
|
||||
pathFrontendWhiteListSourceRange = "/whitelistsourcerange"
|
||||
pathFrontendBasicAuth = "/basicauth"
|
||||
pathFrontendEntryPoints = "/entrypoints"
|
||||
pathFrontendRedirectEntryPoint = "/redirect/entrypoint"
|
||||
pathFrontendRedirectRegex = "/redirect/regex"
|
||||
pathFrontendRedirectReplacement = "/redirect/replacement"
|
||||
pathFrontendErrorPages = "/errors/"
|
||||
pathFrontendErrorPagesBackend = "/backend"
|
||||
pathFrontendErrorPagesQuery = "/query"
|
||||
pathFrontendErrorPagesStatus = "/status"
|
||||
pathFrontendRateLimit = "/ratelimit/"
|
||||
pathFrontendRateLimitRateSet = pathFrontendRateLimit + "rateset/"
|
||||
pathFrontendRateLimitExtractorFunc = pathFrontendRateLimit + "extractorfunc"
|
||||
pathFrontendRateLimitPeriod = "/period"
|
||||
pathFrontendRateLimitAverage = "/average"
|
||||
pathFrontendRateLimitBurst = "/burst"
|
||||
|
||||
pathFrontendCustomRequestHeaders = "/headers/customrequestheaders/"
|
||||
pathFrontendCustomResponseHeaders = "/headers/customresponseheaders/"
|
||||
pathFrontendAllowedHosts = "/headers/allowedhosts"
|
||||
pathFrontendHostsProxyHeaders = "/headers/hostsproxyheaders"
|
||||
pathFrontendSSLRedirect = "/headers/sslredirect"
|
||||
pathFrontendSSLTemporaryRedirect = "/headers/ssltemporaryredirect"
|
||||
pathFrontendSSLHost = "/headers/sslhost"
|
||||
pathFrontendSSLProxyHeaders = "/headers/sslproxyheaders/"
|
||||
pathFrontendSTSSeconds = "/headers/stsseconds"
|
||||
pathFrontendSTSIncludeSubdomains = "/headers/stsincludesubdomains"
|
||||
pathFrontendSTSPreload = "/headers/stspreload"
|
||||
pathFrontendForceSTSHeader = "/headers/forcestsheader"
|
||||
pathFrontendFrameDeny = "/headers/framedeny"
|
||||
pathFrontendCustomFrameOptionsValue = "/headers/customframeoptionsvalue"
|
||||
pathFrontendContentTypeNosniff = "/headers/contenttypenosniff"
|
||||
pathFrontendBrowserXSSFilter = "/headers/browserxssfilter"
|
||||
pathFrontendContentSecurityPolicy = "/headers/contentsecuritypolicy"
|
||||
pathFrontendPublicKey = "/headers/publickey"
|
||||
pathFrontendReferrerPolicy = "/headers/referrerpolicy"
|
||||
pathFrontendIsDevelopment = "/headers/isdevelopment"
|
||||
|
||||
pathFrontendRoutes = "/routes/"
|
||||
pathFrontendRule = "/rule"
|
||||
|
||||
pathTLSConfiguration = "/tlsconfiguration/"
|
||||
pathTLSConfigurationEntryPoints = "/entrypoints"
|
||||
pathTLSConfigurationCertFile = "/certificate/certfile"
|
||||
pathTLSConfigurationKeyFile = "/certificate/keyfile"
|
||||
|
||||
pathTags = "/tags"
|
||||
pathAlias = "/alias"
|
||||
|
|
|
@ -26,8 +26,12 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
"List": p.list,
|
||||
"ListServers": p.listServers,
|
||||
"Get": p.get,
|
||||
"GetBool": p.getBool,
|
||||
"GetInt": p.getInt,
|
||||
"GetInt64": p.getInt64,
|
||||
"SplitGet": p.splitGet,
|
||||
"Last": p.last,
|
||||
"Has": p.has,
|
||||
|
||||
// Backend functions
|
||||
"getSticky": p.getSticky,
|
||||
|
@ -143,6 +147,41 @@ func (p *Provider) getBool(defaultValue bool, keyParts ...string) bool {
|
|||
return value
|
||||
}
|
||||
|
||||
func (p *Provider) has(keyParts ...string) bool {
|
||||
value := p.get("", keyParts...)
|
||||
return len(value) > 0
|
||||
}
|
||||
|
||||
func (p *Provider) getInt(defaultValue int, keyParts ...string) int {
|
||||
rawValue := p.get("", keyParts...)
|
||||
|
||||
if len(rawValue) == 0 {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
value, err := strconv.Atoi(rawValue)
|
||||
if err != nil {
|
||||
log.Errorf("Invalid value for %v: %s", keyParts, rawValue)
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func (p *Provider) getInt64(defaultValue int64, keyParts ...string) int64 {
|
||||
rawValue := p.get("", keyParts...)
|
||||
|
||||
if len(rawValue) == 0 {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
value, err := strconv.ParseInt(rawValue, 10, 64)
|
||||
if err != nil {
|
||||
log.Errorf("Invalid value for %v: %s", keyParts, rawValue)
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func (p *Provider) list(keyParts ...string) []string {
|
||||
rootKey := strings.Join(keyParts, "")
|
||||
|
||||
|
|
|
@ -62,16 +62,16 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
desc: "all parameters",
|
||||
kvPairs: filler("traefik",
|
||||
backend("backend1",
|
||||
withPair("healthcheck/path", "/health"),
|
||||
withPair("healthcheck/port", "80"),
|
||||
withPair("healthcheck/interval", "30s"),
|
||||
withPair("maxconn/amount", "5"),
|
||||
withPair("maxconn/extractorfunc", "client.ip"),
|
||||
withPair(pathBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression),
|
||||
withPair(pathBackendLoadBalancerMethod, "drr"),
|
||||
withPair(pathBackendLoadBalancerSticky, "true"),
|
||||
withPair(pathBackendLoadBalancerStickiness, "true"),
|
||||
withPair(pathBackendLoadBalancerStickinessCookieName, "tomate"),
|
||||
withPair(pathBackendHealthCheckPath, "/health"),
|
||||
withPair(pathBackendHealthCheckPort, "80"),
|
||||
withPair(pathBackendHealthCheckInterval, "30s"),
|
||||
withPair(pathBackendMaxConnAmount, "5"),
|
||||
withPair(pathBackendMaxConnExtractorFunc, "client.ip"),
|
||||
withPair("servers/server1/url", "http://172.17.0.2:80"),
|
||||
withPair("servers/server1/weight", "0"),
|
||||
withPair("servers/server2/weight", "0")),
|
||||
|
@ -525,6 +525,136 @@ func TestProviderGetBool(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestProviderGetInt(t *testing.T) {
|
||||
defaultValue := 666
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
kvPairs []*store.KVPair
|
||||
kvError error
|
||||
keyParts []string
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
desc: "when has value",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair("bar", "6"),
|
||||
),
|
||||
),
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: 6,
|
||||
},
|
||||
{
|
||||
desc: "when empty value",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair("bar", ""),
|
||||
),
|
||||
),
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: defaultValue,
|
||||
},
|
||||
{
|
||||
desc: "when not existing key",
|
||||
kvPairs: nil,
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: defaultValue,
|
||||
},
|
||||
{
|
||||
desc: "when KV error",
|
||||
kvError: store.ErrNotReachable,
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair("bar", "true"),
|
||||
),
|
||||
),
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: defaultValue,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
test := test
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := &Provider{
|
||||
kvClient: newKvClientMock(test.kvPairs, test.kvError),
|
||||
}
|
||||
|
||||
actual := p.getInt(defaultValue, test.keyParts...)
|
||||
|
||||
assert.Equal(t, test.expected, actual, "key: %v", test.keyParts)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetInt64(t *testing.T) {
|
||||
var defaultValue int64 = 666
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
kvPairs []*store.KVPair
|
||||
kvError error
|
||||
keyParts []string
|
||||
expected int64
|
||||
}{
|
||||
{
|
||||
desc: "when has value",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair("bar", "6"),
|
||||
),
|
||||
),
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: 6,
|
||||
},
|
||||
{
|
||||
desc: "when empty value",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair("bar", ""),
|
||||
),
|
||||
),
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: defaultValue,
|
||||
},
|
||||
{
|
||||
desc: "when not existing key",
|
||||
kvPairs: nil,
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: defaultValue,
|
||||
},
|
||||
{
|
||||
desc: "when KV error",
|
||||
kvError: store.ErrNotReachable,
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair("bar", "true"),
|
||||
),
|
||||
),
|
||||
keyParts: []string{"traefik/frontends/foo/bar"},
|
||||
expected: defaultValue,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
test := test
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := &Provider{
|
||||
kvClient: newKvClientMock(test.kvPairs, test.kvError),
|
||||
}
|
||||
|
||||
actual := p.getInt64(defaultValue, test.keyParts...)
|
||||
|
||||
assert.Equal(t, test.expected, actual, "key: %v", test.keyParts)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderHasStickinessLabel(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
Loading…
Reference in a new issue