1
0
Fork 0

feat(docker): add error pages labels.

This commit is contained in:
Fernandez Ludovic 2017-12-18 16:26:04 +01:00 committed by Traefiker
parent 50757b5e99
commit c30ebe5f90
9 changed files with 413 additions and 18 deletions

View file

@ -49,6 +49,8 @@ func (p *Provider) buildConfiguration(containersInspected []dockerData) *types.C
"getRedirectEntryPoint": getFuncStringLabel(label.TraefikFrontendRedirectEntryPoint, label.DefaultFrontendRedirectEntryPoint),
"getRedirectRegex": getFuncStringLabel(label.TraefikFrontendRedirectRegex, ""),
"getRedirectReplacement": getFuncStringLabel(label.TraefikFrontendRedirectReplacement, ""),
"hasErrorPages": hasErrorPages,
"getErrorPages": getErrorPages,
// Headers
"hasRequestHeaders": hasFunc(label.TraefikFrontendRequestHeaders),
"getRequestHeaders": getFuncMapLabel(label.TraefikFrontendRequestHeaders),
@ -114,6 +116,8 @@ func (p *Provider) buildConfiguration(containersInspected []dockerData) *types.C
"getServiceRequestHeaders": getFuncServiceMapLabel(label.SuffixFrontendRequestHeaders),
"hasServiceResponseHeaders": hasFuncServiceLabel(label.SuffixFrontendResponseHeaders),
"getServiceResponseHeaders": getFuncServiceMapLabel(label.SuffixFrontendResponseHeaders),
"hasServiceErrorPages": hasServiceErrorPages,
"getServiceErrorPages": getServiceErrorPages,
}
// filter containers
filteredContainers := fun.Filter(func(container dockerData) bool {

View file

@ -8,6 +8,7 @@ import (
"github.com/containous/traefik/log"
"github.com/containous/traefik/provider"
"github.com/containous/traefik/provider/label"
"github.com/containous/traefik/types"
"github.com/docker/go-connections/nat"
)
@ -172,6 +173,15 @@ func hasRedirect(container dockerData) bool {
label.Has(container.Labels, label.TraefikFrontendRedirectReplacement) && label.Has(container.Labels, label.TraefikFrontendRedirectRegex)
}
func hasErrorPages(container dockerData) bool {
return label.HasPrefix(container.Labels, label.Prefix+label.BaseFrontendErrorPage)
}
func getErrorPages(container dockerData) map[string]*types.ErrorPage {
prefix := label.Prefix + label.BaseFrontendErrorPage
return label.ParseErrorPages(container.Labels, prefix, label.RegexpFrontendErrorPage)
}
// Label functions
func getFuncInt64Label(labelName string, defaultValue int64) func(container dockerData) int64 {

View file

@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require"
)
func TestDockerLoadDockerConfig(t *testing.T) {
func TestDockerBuildConfiguration(t *testing.T) {
testCases := []struct {
containers []docker.ContainerJSON
expectedFrontends map[string]*types.Frontend
@ -181,6 +181,61 @@ func TestDockerLoadDockerConfig(t *testing.T) {
},
},
},
{
containers: []docker.ContainerJSON{
containerJSON(
name("test1"),
labels(map[string]string{
label.TraefikBackend: "foobar",
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: "404",
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: "foobar",
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: "foo_query",
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: "500,600",
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: "foobar",
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: "bar_query",
}),
ports(nat.PortMap{
"80/tcp": {},
}),
withNetwork("bridge", ipv4("127.0.0.1")),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test1-docker-localhost-0": {
EntryPoints: []string{},
BasicAuth: []string{},
PassHostHeader: true,
Backend: "backend-foobar",
Routes: map[string]types.Route{
"route-frontend-Host-test1-docker-localhost-0": {
Rule: "Host:test1.docker.localhost",
},
},
Errors: map[string]types.ErrorPage{
"foo": {
Status: []string{"404"},
Query: "foo_query",
Backend: "foobar",
},
"bar": {
Status: []string{"500", "600"},
Query: "bar_query",
Backend: "foobar",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foobar": {
Servers: map[string]types.Server{
"server-test1": {
URL: "http://127.0.0.1:80",
Weight: 0,
},
},
},
},
},
}
for caseID, test := range testCases {
@ -897,3 +952,59 @@ func TestDockerGetPort(t *testing.T) {
})
}
}
func TestGetErrorPages(t *testing.T) {
testCases := []struct {
desc string
data dockerData
expected map[string]*types.ErrorPage
}{
{
desc: "2 errors pages",
data: parseContainer(containerJSON(
labels(map[string]string{
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: "404",
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: "foo_backend",
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: "foo_query",
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: "500,600",
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: "bar_backend",
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: "bar_query",
}))),
expected: map[string]*types.ErrorPage{
"foo": {
Status: []string{"404"},
Query: "foo_query",
Backend: "foo_backend",
},
"bar": {
Status: []string{"500", "600"},
Query: "bar_query",
Backend: "bar_backend",
},
},
},
{
desc: "only status field",
data: parseContainer(containerJSON(
labels(map[string]string{
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: "404",
}))),
expected: map[string]*types.ErrorPage{
"foo": {
Status: []string{"404"},
},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
pages := getErrorPages(test.data)
assert.EqualValues(t, test.expected, pages)
})
}
}

View file

@ -7,6 +7,7 @@ import (
"github.com/containous/traefik/provider"
"github.com/containous/traefik/provider/label"
"github.com/containous/traefik/types"
)
// Specific functions
@ -50,7 +51,8 @@ func checkServiceLabelPort(container dockerData) error {
}
// Get only one instance of all service names from service labels
servicesLabelNames := label.ServicesPropertiesRegexp.FindStringSubmatch(lbl)
if len(servicesLabelNames) > 0 {
if len(servicesLabelNames) > 0 && !strings.HasPrefix(lbl, label.TraefikFrontend) {
serviceLabels[strings.Split(servicesLabelNames[0], ".")[1]] = struct{}{}
}
}
@ -96,6 +98,16 @@ func hasServiceRedirect(container dockerData, serviceName string) bool {
label.Has(serviceLabels, label.SuffixFrontendRedirectRegex) && label.Has(serviceLabels, label.SuffixFrontendRedirectReplacement)
}
func hasServiceErrorPages(container dockerData, serviceName string) bool {
serviceLabels := getServiceLabels(container, serviceName)
return label.HasPrefix(serviceLabels, label.BaseFrontendErrorPage)
}
func getServiceErrorPages(container dockerData, serviceName string) map[string]*types.ErrorPage {
serviceLabels := getServiceLabels(container, serviceName)
return label.ParseErrorPages(serviceLabels, label.BaseFrontendErrorPage, label.RegexpBaseFrontendErrorPage)
}
// Service label functions
func getFuncServiceMapLabel(labelSuffix string) func(container dockerData, serviceName string) map[string]string {

View file

@ -6,6 +6,7 @@ import (
"testing"
"github.com/containous/traefik/provider/label"
"github.com/containous/traefik/types"
docker "github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)
@ -219,3 +220,60 @@ func TestDockerCheckPortLabels(t *testing.T) {
})
}
}
func TestGetServiceErrorPages(t *testing.T) {
service := "courgette"
testCases := []struct {
desc string
data dockerData
expected map[string]*types.ErrorPage
}{
{
desc: "2 errors pages",
data: parseContainer(containerJSON(
labels(map[string]string{
label.Prefix + service + "." + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: "404",
label.Prefix + service + "." + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: "foo_backend",
label.Prefix + service + "." + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: "foo_query",
label.Prefix + service + "." + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: "500,600",
label.Prefix + service + "." + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: "bar_backend",
label.Prefix + service + "." + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: "bar_query",
}))),
expected: map[string]*types.ErrorPage{
"foo": {
Status: []string{"404"},
Query: "foo_query",
Backend: "foo_backend",
},
"bar": {
Status: []string{"500", "600"},
Query: "bar_query",
Backend: "bar_backend",
},
},
},
{
desc: "only status field",
data: parseContainer(containerJSON(
labels(map[string]string{
label.Prefix + service + ".frontend.errors.foo.status": "404",
}))),
expected: map[string]*types.ErrorPage{
"foo": {
Status: []string{"404"},
},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
pages := getServiceErrorPages(test.data, service)
assert.EqualValues(t, test.expected, pages)
})
}
}