Fix Docker filter empty rule

Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
Emile Vauge 2017-04-07 16:30:57 +02:00
parent ec245d604a
commit bf3f6e2029
No known key found for this signature in database
GPG key ID: D808B4C167352E59
3 changed files with 352 additions and 144 deletions

View file

@ -523,6 +523,11 @@ func (p *Provider) containerFilter(container dockerData) bool {
return false return false
} }
if len(p.getFrontendRule(container)) == 0 {
log.Debugf("Filtering container with empty frontend rule %s", container.Name)
return false
}
return true return true
} }
@ -537,11 +542,10 @@ func (p *Provider) getFrontendRule(container dockerData) string {
if label, err := getLabel(container, "traefik.frontend.rule"); err == nil { if label, err := getLabel(container, "traefik.frontend.rule"); err == nil {
return label return label
} }
if labels, err := getLabels(container, []string{"com.docker.compose.project", "com.docker.compose.service"}); err == nil { if len(p.Domain) > 0 {
return "Host:" + p.getSubDomain(labels["com.docker.compose.service"]+"."+labels["com.docker.compose.project"]) + "." + p.Domain return "Host:" + p.getSubDomain(container.ServiceName) + "." + p.Domain
} }
return ""
return "Host:" + p.getSubDomain(container.ServiceName) + "." + p.Domain
} }
func (p *Provider) getBackend(container dockerData) string { func (p *Provider) getBackend(container dockerData) string {

View file

@ -8,6 +8,7 @@ import (
"github.com/containous/traefik/types" "github.com/containous/traefik/types"
docker "github.com/docker/engine-api/types" docker "github.com/docker/engine-api/types"
"github.com/docker/engine-api/types/container"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
) )
@ -488,127 +489,300 @@ func TestDockerGetLabels(t *testing.T) {
func TestDockerTraefikFilter(t *testing.T) { func TestDockerTraefikFilter(t *testing.T) {
containers := []struct { containers := []struct {
container docker.ContainerJSON container docker.ContainerJSON
exposedByDefault bool expected bool
expected bool provider *Provider
}{ }{
{ {
container: containerJSON(), container: docker.ContainerJSON{
exposedByDefault: true, ContainerJSONBase: &docker.ContainerJSONBase{
expected: false, Name: "container",
},
Config: &container.Config{},
NetworkSettings: &docker.NetworkSettings{},
},
expected: false,
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
labels(map[string]string{ ContainerJSONBase: &docker.ContainerJSONBase{
"traefik.enable": "false", Name: "container",
}), },
ports(nat.PortMap{ Config: &container.Config{
"80/tcp": {}, Labels: map[string]string{
}), "traefik.enable": "false",
), },
exposedByDefault: true, },
expected: false, NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: false,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
labels(map[string]string{ ContainerJSONBase: &docker.ContainerJSONBase{
"traefik.frontend.rule": "Host:foo.bar", Name: "container",
}), },
ports(nat.PortMap{ Config: &container.Config{
"80/tcp": {}, Labels: map[string]string{
}), "traefik.frontend.rule": "Host:foo.bar",
), },
exposedByDefault: true, },
expected: true, NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: true,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
ports(nat.PortMap{ ContainerJSONBase: &docker.ContainerJSONBase{
"80/tcp": {}, Name: "container-multi-ports",
"443/tcp": {}, },
}), Config: &container.Config{},
), NetworkSettings: &docker.NetworkSettings{
exposedByDefault: true, NetworkSettingsBase: docker.NetworkSettingsBase{
expected: true, Ports: nat.PortMap{
"80/tcp": {},
"443/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: true,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
ports(nat.PortMap{ ContainerJSONBase: &docker.ContainerJSONBase{
"80/tcp": {}, Name: "container",
}), },
), Config: &container.Config{},
exposedByDefault: true, NetworkSettings: &docker.NetworkSettings{
expected: true, NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: true,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
labels(map[string]string{ ContainerJSONBase: &docker.ContainerJSONBase{
"traefik.port": "80", Name: "container",
}), },
ports(nat.PortMap{ Config: &container.Config{
"80/tcp": {}, Labels: map[string]string{
"443/tcp": {}, "traefik.port": "80",
}), },
), },
exposedByDefault: true, NetworkSettings: &docker.NetworkSettings{
expected: true, NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
"443/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: true,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
labels(map[string]string{ ContainerJSONBase: &docker.ContainerJSONBase{
"traefik.enable": "true", Name: "container",
}), },
ports(nat.PortMap{ Config: &container.Config{
"80/tcp": {}, Labels: map[string]string{
}), "traefik.enable": "true",
), },
exposedByDefault: true, },
expected: true, NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: true,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
labels(map[string]string{ ContainerJSONBase: &docker.ContainerJSONBase{
"traefik.enable": "anything", Name: "container",
}), },
ports(nat.PortMap{ Config: &container.Config{
"80/tcp": {}, Labels: map[string]string{
}), "traefik.enable": "anything",
), },
exposedByDefault: true, },
expected: true, NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: true,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
labels(map[string]string{ ContainerJSONBase: &docker.ContainerJSONBase{
"traefik.frontend.rule": "Host:foo.bar", Name: "container",
}), },
ports(nat.PortMap{ Config: &container.Config{
"80/tcp": {}, Labels: map[string]string{
}), "traefik.frontend.rule": "Host:foo.bar",
), },
exposedByDefault: true, },
expected: true, NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: true,
},
expected: true,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
ports(nat.PortMap{ ContainerJSONBase: &docker.ContainerJSONBase{
"80/tcp": {}, Name: "container",
}), },
), Config: &container.Config{},
exposedByDefault: false, NetworkSettings: &docker.NetworkSettings{
expected: false, NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: false,
},
expected: false,
}, },
{ {
container: containerJSON( container: docker.ContainerJSON{
labels(map[string]string{ ContainerJSONBase: &docker.ContainerJSONBase{
"traefik.enable": "true", Name: "container",
}), },
ports(nat.PortMap{ Config: &container.Config{
"80/tcp": {}, Labels: map[string]string{
}), "traefik.enable": "true",
), },
exposedByDefault: false, },
expected: true, NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
Domain: "test",
ExposedByDefault: false,
},
expected: true,
},
{
container: docker.ContainerJSON{
ContainerJSONBase: &docker.ContainerJSONBase{
Name: "container",
},
Config: &container.Config{
Labels: map[string]string{
"traefik.enable": "true",
},
},
NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
ExposedByDefault: false,
},
expected: false,
},
{
container: docker.ContainerJSON{
ContainerJSONBase: &docker.ContainerJSONBase{
Name: "container",
},
Config: &container.Config{
Labels: map[string]string{
"traefik.enable": "true",
"traefik.frontend.rule": "Host:i.love.this.host",
},
},
NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"80/tcp": {},
},
},
},
},
provider: &Provider{
ExposedByDefault: false,
},
expected: true,
}, },
} }
@ -616,12 +790,10 @@ func TestDockerTraefikFilter(t *testing.T) {
e := e e := e
t.Run(strconv.Itoa(containerID), func(t *testing.T) { t.Run(strconv.Itoa(containerID), func(t *testing.T) {
t.Parallel() t.Parallel()
provider := Provider{}
provider.ExposedByDefault = e.exposedByDefault
dockerData := parseContainer(e.container) dockerData := parseContainer(e.container)
actual := provider.containerFilter(dockerData) actual := e.provider.containerFilter(dockerData)
if actual != e.expected { if actual != e.expected {
t.Errorf("expected %v for %+v (%+v, %+v), got %+v", e.expected, e.container, e.container.NetworkSettings, e.container.ContainerJSONBase, actual) t.Errorf("expected %v for %+v, got %+v", e.expected, e, actual)
} }
}) })
} }

View file

@ -503,86 +503,122 @@ func TestSwarmGetLabels(t *testing.T) {
func TestSwarmTraefikFilter(t *testing.T) { func TestSwarmTraefikFilter(t *testing.T) {
services := []struct { services := []struct {
service swarm.Service service swarm.Service
exposedByDefault bool expected bool
expected bool networks map[string]*docker.NetworkResource
networks map[string]*docker.NetworkResource provider *Provider
}{ }{
{ {
service: swarmService(), service: swarmService(),
exposedByDefault: true, expected: false,
expected: false, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.enable": "false", "traefik.enable": "false",
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: true, expected: false,
expected: false, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.frontend.rule": "Host:foo.bar", "traefik.frontend.rule": "Host:foo.bar",
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: true, expected: true,
expected: true, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: true, expected: true,
expected: true, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.enable": "true", "traefik.enable": "true",
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: true, expected: true,
expected: true, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.enable": "anything", "traefik.enable": "anything",
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: true, expected: true,
expected: true, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.frontend.rule": "Host:foo.bar", "traefik.frontend.rule": "Host:foo.bar",
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: true, expected: true,
expected: true, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: true,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: false, expected: false,
expected: false, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: false,
},
}, },
{ {
service: swarmService(serviceLabels(map[string]string{ service: swarmService(serviceLabels(map[string]string{
"traefik.enable": "true", "traefik.enable": "true",
"traefik.port": "80", "traefik.port": "80",
})), })),
exposedByDefault: false, expected: true,
expected: true, networks: map[string]*docker.NetworkResource{},
networks: map[string]*docker.NetworkResource{}, provider: &Provider{
SwarmMode: true,
Domain: "test",
ExposedByDefault: false,
},
}, },
} }
@ -591,11 +627,7 @@ func TestSwarmTraefikFilter(t *testing.T) {
t.Run(strconv.Itoa(serviceID), func(t *testing.T) { t.Run(strconv.Itoa(serviceID), func(t *testing.T) {
t.Parallel() t.Parallel()
dockerData := parseService(e.service, e.networks) dockerData := parseService(e.service, e.networks)
provider := &Provider{ actual := e.provider.containerFilter(dockerData)
SwarmMode: true,
}
provider.ExposedByDefault = e.exposedByDefault
actual := provider.containerFilter(dockerData)
if actual != e.expected { if actual != e.expected {
t.Errorf("expected %v for %+v, got %+v", e.expected, e, actual) t.Errorf("expected %v for %+v, got %+v", e.expected, e, actual)
} }