Make frontend names differents for similar routes

This commit is contained in:
NicoMen 2017-10-30 12:06:03 +01:00 committed by Traefiker
parent 9b5845f1cb
commit da7b6f0baf
4 changed files with 45 additions and 32 deletions

View file

@ -129,6 +129,11 @@ func (s *DockerSuite) TestDockerContainersWithLabels(c *check.C) {
} }
s.startContainerWithLabels(c, "swarm:1.0.0", labels, "manage", "token://blabla") s.startContainerWithLabels(c, "swarm:1.0.0", labels, "manage", "token://blabla")
// Start another container by replacing a '.' by a '-'
labels = map[string]string{
types.LabelFrontendRule: "Host:my-super.host",
}
s.startContainerWithLabels(c, "swarm:1.0.0", labels, "manage", "token://blablabla")
// Start traefik // Start traefik
cmd, display := s.traefikCmd(withConfigFile(file)) cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c) defer display(c)
@ -138,12 +143,20 @@ func (s *DockerSuite) TestDockerContainersWithLabels(c *check.C) {
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil) req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
req.Host = "my.super.host" req.Host = "my-super.host"
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?) // FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK) resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)
req.Host = "my.super.host"
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
resp, err = try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
c.Assert(err, checker.IsNil)
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)

View file

@ -301,8 +301,8 @@ func (p *Provider) loadDockerConfig(containersInspected []dockerData) *types.Con
frontends := map[string][]dockerData{} frontends := map[string][]dockerData{}
backends := map[string]dockerData{} backends := map[string]dockerData{}
servers := map[string][]dockerData{} servers := map[string][]dockerData{}
for _, container := range filteredContainers { for idx, container := range filteredContainers {
frontendName := p.getFrontendName(container) frontendName := p.getFrontendName(container, idx)
frontends[frontendName] = append(frontends[frontendName], container) frontends[frontendName] = append(frontends[frontendName], container)
backendName := p.getBackend(container) backendName := p.getBackend(container)
backends[backendName] = container backends[backendName] = container
@ -549,9 +549,9 @@ func (p *Provider) containerFilter(container dockerData) bool {
return true return true
} }
func (p *Provider) getFrontendName(container dockerData) string { func (p *Provider) getFrontendName(container dockerData, idx int) string {
// Replace '.' with '-' in quoted keys because of this issue https://github.com/BurntSushi/toml/issues/78 // Replace '.' with '-' in quoted keys because of this issue https://github.com/BurntSushi/toml/issues/78
return provider.Normalize(p.getFrontendRule(container)) return provider.Normalize(p.getFrontendRule(container) + "-" + strconv.Itoa(idx))
} }
// GetFrontendRule returns the frontend rule for the specified container, using // GetFrontendRule returns the frontend rule for the specified container, using

View file

@ -20,38 +20,38 @@ func TestDockerGetFrontendName(t *testing.T) {
}{ }{
{ {
container: containerJSON(name("foo")), container: containerJSON(name("foo")),
expected: "Host-foo-docker-localhost", expected: "Host-foo-docker-localhost-0",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{
types.LabelFrontendRule: "Headers:User-Agent,bat/0.1.0", types.LabelFrontendRule: "Headers:User-Agent,bat/0.1.0",
})), })),
expected: "Headers-User-Agent-bat-0-1-0", expected: "Headers-User-Agent-bat-0-1-0-0",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{
"com.docker.compose.project": "foo", "com.docker.compose.project": "foo",
"com.docker.compose.service": "bar", "com.docker.compose.service": "bar",
})), })),
expected: "Host-bar-foo-docker-localhost", expected: "Host-bar-foo-docker-localhost-0",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{
types.LabelFrontendRule: "Host:foo.bar", types.LabelFrontendRule: "Host:foo.bar",
})), })),
expected: "Host-foo-bar", expected: "Host-foo-bar-0",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{
types.LabelFrontendRule: "Path:/test", types.LabelFrontendRule: "Path:/test",
})), })),
expected: "Path-test", expected: "Path-test-0",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{
types.LabelFrontendRule: "PathPrefix:/test2", types.LabelFrontendRule: "PathPrefix:/test2",
})), })),
expected: "PathPrefix-test2", expected: "PathPrefix-test2-0",
}, },
} }
@ -63,7 +63,7 @@ func TestDockerGetFrontendName(t *testing.T) {
provider := &Provider{ provider := &Provider{
Domain: "docker.localhost", Domain: "docker.localhost",
} }
actual := provider.getFrontendName(dockerData) actual := provider.getFrontendName(dockerData, 0)
if actual != e.expected { if actual != e.expected {
t.Errorf("expected %q, got %q", e.expected, actual) t.Errorf("expected %q, got %q", e.expected, actual)
} }
@ -884,13 +884,13 @@ func TestDockerLoadDockerConfig(t *testing.T) {
), ),
}, },
expectedFrontends: map[string]*types.Frontend{ expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost": { "frontend-Host-test-docker-localhost-0": {
Backend: "backend-test", Backend: "backend-test",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{}, BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost": { "route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost", Rule: "Host:test.docker.localhost",
}, },
}, },
@ -934,24 +934,24 @@ func TestDockerLoadDockerConfig(t *testing.T) {
), ),
}, },
expectedFrontends: map[string]*types.Frontend{ expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test1-docker-localhost": { "frontend-Host-test1-docker-localhost-0": {
Backend: "backend-foobar", Backend: "backend-foobar",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test1-docker-localhost": { "route-frontend-Host-test1-docker-localhost-0": {
Rule: "Host:test1.docker.localhost", Rule: "Host:test1.docker.localhost",
}, },
}, },
}, },
"frontend-Host-test2-docker-localhost": { "frontend-Host-test2-docker-localhost-1": {
Backend: "backend-foobar", Backend: "backend-foobar",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{}, BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test2-docker-localhost": { "route-frontend-Host-test2-docker-localhost-1": {
Rule: "Host:test2.docker.localhost", Rule: "Host:test2.docker.localhost",
}, },
}, },
@ -992,13 +992,13 @@ func TestDockerLoadDockerConfig(t *testing.T) {
), ),
}, },
expectedFrontends: map[string]*types.Frontend{ expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test1-docker-localhost": { "frontend-Host-test1-docker-localhost-0": {
Backend: "backend-foobar", Backend: "backend-foobar",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{}, BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test1-docker-localhost": { "route-frontend-Host-test1-docker-localhost-0": {
Rule: "Host:test1.docker.localhost", Rule: "Host:test1.docker.localhost",
}, },
}, },

View file

@ -23,28 +23,28 @@ func TestSwarmGetFrontendName(t *testing.T) {
}{ }{
{ {
service: swarmService(serviceName("foo")), service: swarmService(serviceName("foo")),
expected: "Host-foo-docker-localhost", expected: "Host-foo-docker-localhost-0",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
types.LabelFrontendRule: "Headers:User-Agent,bat/0.1.0", types.LabelFrontendRule: "Headers:User-Agent,bat/0.1.0",
})), })),
expected: "Headers-User-Agent-bat-0-1-0", expected: "Headers-User-Agent-bat-0-1-0-0",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
types.LabelFrontendRule: "Host:foo.bar", types.LabelFrontendRule: "Host:foo.bar",
})), })),
expected: "Host-foo-bar", expected: "Host-foo-bar-0",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
types.LabelFrontendRule: "Path:/test", types.LabelFrontendRule: "Path:/test",
})), })),
expected: "Path-test", expected: "Path-test-0",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
{ {
@ -54,7 +54,7 @@ func TestSwarmGetFrontendName(t *testing.T) {
types.LabelFrontendRule: "PathPrefix:/test2", types.LabelFrontendRule: "PathPrefix:/test2",
}), }),
), ),
expected: "PathPrefix-test2", expected: "PathPrefix-test2-0",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
} }
@ -68,7 +68,7 @@ func TestSwarmGetFrontendName(t *testing.T) {
Domain: "docker.localhost", Domain: "docker.localhost",
SwarmMode: true, SwarmMode: true,
} }
actual := provider.getFrontendName(dockerData) actual := provider.getFrontendName(dockerData, 0)
if actual != e.expected { if actual != e.expected {
t.Errorf("expected %q, got %q", e.expected, actual) t.Errorf("expected %q, got %q", e.expected, actual)
} }
@ -660,13 +660,13 @@ func TestSwarmLoadDockerConfig(t *testing.T) {
), ),
}, },
expectedFrontends: map[string]*types.Frontend{ expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test-docker-localhost": { "frontend-Host-test-docker-localhost-0": {
Backend: "backend-test", Backend: "backend-test",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{}, BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test-docker-localhost": { "route-frontend-Host-test-docker-localhost-0": {
Rule: "Host:test.docker.localhost", Rule: "Host:test.docker.localhost",
}, },
}, },
@ -714,24 +714,24 @@ func TestSwarmLoadDockerConfig(t *testing.T) {
), ),
}, },
expectedFrontends: map[string]*types.Frontend{ expectedFrontends: map[string]*types.Frontend{
"frontend-Host-test1-docker-localhost": { "frontend-Host-test1-docker-localhost-0": {
Backend: "backend-foobar", Backend: "backend-foobar",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{"http", "https"}, EntryPoints: []string{"http", "https"},
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test1-docker-localhost": { "route-frontend-Host-test1-docker-localhost-0": {
Rule: "Host:test1.docker.localhost", Rule: "Host:test1.docker.localhost",
}, },
}, },
}, },
"frontend-Host-test2-docker-localhost": { "frontend-Host-test2-docker-localhost-1": {
Backend: "backend-foobar", Backend: "backend-foobar",
PassHostHeader: true, PassHostHeader: true,
EntryPoints: []string{}, EntryPoints: []string{},
BasicAuth: []string{}, BasicAuth: []string{},
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"route-frontend-Host-test2-docker-localhost": { "route-frontend-Host-test2-docker-localhost-1": {
Rule: "Host:test2.docker.localhost", Rule: "Host:test2.docker.localhost",
}, },
}, },