From 51390aa874b517b998adbc3951ff6a38ef17c477 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 3 Jan 2018 16:39:37 +0100 Subject: [PATCH] feat(kv): add error pages configuration. --- provider/kv/filler_test.go | 12 +++++++++ provider/kv/kv_config.go | 24 +++++++++++++++++ provider/kv/kv_config_test.go | 49 +++++++++++++++++++++++++++++++++++ templates/kv.tmpl | 13 ++++++++++ 4 files changed, 98 insertions(+) diff --git a/provider/kv/filler_test.go b/provider/kv/filler_test.go index 22505756d..9c88aa5a6 100644 --- a/provider/kv/filler_test.go +++ b/provider/kv/filler_test.go @@ -81,6 +81,18 @@ func withPair(key string, value string) func(map[string]string) { } } +func withErrorPage(name string, backend, query, status string) func(map[string]string) { + return func(pairs map[string]string) { + if len(name) == 0 { + return + } + + withPair(pathFrontendErrorPages+name+pathFrontendErrorPagesBackend, backend)(pairs) + withPair(pathFrontendErrorPages+name+pathFrontendErrorPagesQuery, query)(pairs) + withPair(pathFrontendErrorPages+name+pathFrontendErrorPagesStatus, status)(pairs) + } +} + func TestFiller(t *testing.T) { expected := []*store.KVPair{ {Key: "traefik/backends/backend.with.dot.too", Value: []byte("")}, diff --git a/provider/kv/kv_config.go b/provider/kv/kv_config.go index 8fee729db..f13833b7a 100644 --- a/provider/kv/kv_config.go +++ b/provider/kv/kv_config.go @@ -35,6 +35,8 @@ func (p *Provider) buildConfiguration() *types.Configuration { // Frontend functions "getRedirect": p.getRedirect, + "getErrorPages": p.getErrorPages, + // Backend functions "getSticky": p.getSticky, "hasStickinessLabel": p.hasStickinessLabel, @@ -96,6 +98,28 @@ func (p *Provider) getRedirect(rootPath string) *types.Redirect { return nil } +func (p *Provider) getErrorPages(rootPath string) map[string]*types.ErrorPage { + var errorPages map[string]*types.ErrorPage + + pathErrors := p.list(rootPath, pathFrontendErrorPages) + + for _, pathPage := range pathErrors { + if errorPages == nil { + errorPages = make(map[string]*types.ErrorPage) + } + + pageName := p.last(pathPage) + + errorPages[pageName] = &types.ErrorPage{ + Backend: p.get("", pathPage, pathFrontendErrorPagesBackend), + Query: p.get("", pathPage, pathFrontendErrorPagesQuery), + Status: p.splitGet(pathPage, pathFrontendErrorPagesStatus), + } + } + + return errorPages +} + func (p *Provider) listServers(backend string) []string { serverNames := p.list(backend, pathBackendServers) return fun.Filter(p.serverFilter, serverNames).([]string) diff --git a/provider/kv/kv_config_test.go b/provider/kv/kv_config_test.go index c4e3cc031..4b00caf12 100644 --- a/provider/kv/kv_config_test.go +++ b/provider/kv/kv_config_test.go @@ -770,3 +770,52 @@ func TestProviderGetRedirect(t *testing.T) { }) } } + +func TestProviderGetErrorPages(t *testing.T) { + testCases := []struct { + desc string + rootPath string + kvPairs []*store.KVPair + expected map[string]*types.ErrorPage + }{ + { + desc: "2 errors pages", + rootPath: "traefik/frontends/foo", + kvPairs: filler("traefik", + frontend("foo", + withErrorPage("foo", "error", "/test1", "500-501, 503-599"), + withErrorPage("bar", "error", "/test2", "400-405"))), + expected: map[string]*types.ErrorPage{ + "foo": { + Backend: "error", + Query: "/test1", + Status: []string{"500-501", "503-599"}, + }, + "bar": { + Backend: "error", + Query: "/test2", + Status: []string{"400-405"}, + }, + }, + }, + { + desc: "return nil when no errors pages", + rootPath: "traefik/frontends/foo", + kvPairs: filler("traefik", frontend("foo")), + expected: nil, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + p := newProviderMock(test.kvPairs) + + actual := p.getErrorPages(test.rootPath) + + assert.Equal(t, test.expected, actual) + }) + } +} diff --git a/templates/kv.tmpl b/templates/kv.tmpl index 3d9dbda71..0952a5388 100644 --- a/templates/kv.tmpl +++ b/templates/kv.tmpl @@ -78,6 +78,19 @@ replacement = "{{ $redirect.Replacement }}" {{end}} + {{ $errorPages := getErrorPages $frontend }} + {{ if $errorPages }} + [frontends."{{$frontendName}}".errors] + {{ range $pageName, $page := $errorPages }} + [frontends."{{$frontendName}}".errors.{{ $pageName }}] + status = [{{range $page.Status}} + "{{.}}", + {{end}}] + backend = "{{$page.Backend}}" + query = "{{$page.Query}}" + {{end}} + {{end}} + {{range $route := List $frontend "/routes/"}} [frontends."{{$frontendName}}".routes."{{Last $route}}"] rule = "{{Get "" $route "/rule"}}"