From 93a46089ce4111f9e3039d1488d7160cdbf45035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20P?= Date: Tue, 31 Oct 2017 11:44:03 +0100 Subject: [PATCH] Support Host NetworkMode for ECS provider --- docs/configuration/backends/ecs.md | 1 + provider/ecs/ecs.go | 5 ++- provider/ecs/ecs_test.go | 65 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/docs/configuration/backends/ecs.md b/docs/configuration/backends/ecs.md index b19373009..857e58572 100644 --- a/docs/configuration/backends/ecs.md +++ b/docs/configuration/backends/ecs.md @@ -129,6 +129,7 @@ Labels can be used on task containers to override default behaviour: | `traefik.protocol=https` | override the default `http` protocol | | `traefik.weight=10` | assign this weight to the container | | `traefik.enable=false` | disable this container in Træfik | +| `traefik.port=80` | override the default `port` value. Overrides `NetworkBindings` from Docker Container | | `traefik.backend.loadbalancer.method=drr` | override the default `wrr` load balancer algorithm | | `traefik.backend.loadbalancer.stickiness=true` | enable backend sticky sessions | | `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | diff --git a/provider/ecs/ecs.go b/provider/ecs/ecs.go index a1df800e1..c3756e8e6 100644 --- a/provider/ecs/ecs.go +++ b/provider/ecs/ecs.go @@ -429,7 +429,7 @@ func (p *Provider) label(i ecsInstance, k string) string { } func (p *Provider) filterInstance(i ecsInstance) bool { - if len(i.container.NetworkBindings) == 0 { + if labelPort := p.label(i, types.LabelPort); len(i.container.NetworkBindings) == 0 && labelPort == "" { log.Debugf("Filtering ecs instance without port %s (%s)", i.Name, i.ID) return false } @@ -554,6 +554,9 @@ func (p *Provider) getHost(i ecsInstance) string { } func (p *Provider) getPort(i ecsInstance) string { + if port := p.label(i, types.LabelPort); port != "" { + return port + } return strconv.FormatInt(*i.container.NetworkBindings[0].HostPort, 10) } diff --git a/provider/ecs/ecs_test.go b/provider/ecs/ecs_test.go index c3dd5a1fc..69e60f862 100644 --- a/provider/ecs/ecs_test.go +++ b/provider/ecs/ecs_test.go @@ -57,6 +57,14 @@ func simpleEcsInstance(labels map[string]*string) ecsInstance { }) } +func simpleEcsInstanceNoNetwork(labels map[string]*string) ecsInstance { + return makeEcsInstance(&ecs.ContainerDefinition{ + Name: aws.String("http"), + PortMappings: []*ecs.PortMapping{}, + DockerLabels: labels, + }) +} + func TestEcsProtocol(t *testing.T) { tests := []struct { desc string @@ -337,6 +345,12 @@ func TestFilterInstance(t *testing.T) { invalidMachineState := simpleEcsInstance(map[string]*string{}) invalidMachineState.machine.State.Name = aws.String(ec2.InstanceStateNameStopped) + noNetwork := simpleEcsInstanceNoNetwork(map[string]*string{}) + + noNetworkWithLabel := simpleEcsInstanceNoNetwork(map[string]*string{ + types.LabelPort: aws.String("80"), + }) + tests := []struct { desc string expected bool @@ -419,6 +433,22 @@ func TestFilterInstance(t *testing.T) { ExposedByDefault: true, }, }, + { + desc: "Instance with no port mappings should be filtered", + expected: false, + instanceInfo: noNetwork, + provider: &Provider{ + ExposedByDefault: true, + }, + }, + { + desc: "Instance with no port mapping and with label should not be filtered", + expected: true, + instanceInfo: noNetworkWithLabel, + provider: &Provider{ + ExposedByDefault: true, + }, + }, } for _, test := range tests { @@ -623,3 +653,38 @@ func TestGenerateECSConfig(t *testing.T) { }) } } + +func TestEcsWithoutPort(t *testing.T) { + tests := []struct { + desc string + expected string + instanceInfo ecsInstance + provider *Provider + }{ + { + desc: "Label should override network port", + expected: "4242", + instanceInfo: simpleEcsInstance(map[string]*string{ + types.LabelPort: aws.String("4242"), + }), + provider: &Provider{}, + }, + { + desc: "Label should provide exposed port", + expected: "80", + instanceInfo: simpleEcsInstanceNoNetwork(map[string]*string{ + types.LabelPort: aws.String("80"), + }), + provider: &Provider{}, + }, + } + + for _, test := range tests { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + actual := test.provider.getPort(test.instanceInfo) + assert.Equal(t, test.expected, actual) + }) + } +}