1
0
Fork 0

Merge branch 'v1.7' into master

This commit is contained in:
Fernandez Ludovic 2018-08-28 15:50:00 +02:00
commit 4055654e9b
63 changed files with 2687 additions and 852 deletions

View file

@ -0,0 +1,80 @@
package ecs
import (
"github.com/aws/aws-sdk-go/service/ecs"
)
func instance(ops ...func(*ecsInstance)) ecsInstance {
e := &ecsInstance{
containerDefinition: &ecs.ContainerDefinition{},
}
for _, op := range ops {
op(e)
}
return *e
}
func name(name string) func(*ecsInstance) {
return func(e *ecsInstance) {
e.Name = name
}
}
func ID(ID string) func(*ecsInstance) {
return func(e *ecsInstance) {
e.ID = ID
}
}
func iMachine(opts ...func(*machine)) func(*ecsInstance) {
return func(e *ecsInstance) {
e.machine = &machine{}
for _, opt := range opts {
opt(e.machine)
}
}
}
func mState(state string) func(*machine) {
return func(m *machine) {
m.state = state
}
}
func mPrivateIP(ip string) func(*machine) {
return func(m *machine) {
m.privateIP = ip
}
}
func mPorts(opts ...func(*portMapping)) func(*machine) {
return func(m *machine) {
for _, opt := range opts {
p := &portMapping{}
opt(p)
m.ports = append(m.ports, *p)
}
}
}
func mPort(containerPort int32, hostPort int32) func(*portMapping) {
return func(pm *portMapping) {
pm.containerPort = int64(containerPort)
pm.hostPort = int64(hostPort)
}
}
func labels(labels map[string]string) func(*ecsInstance) {
return func(c *ecsInstance) {
c.TraefikLabels = labels
}
}
func dockerLabels(labels map[string]*string) func(*ecsInstance) {
return func(c *ecsInstance) {
c.containerDefinition.DockerLabels = labels
}
}

View file

@ -1,6 +1,8 @@
package ecs
import (
"crypto/md5"
"encoding/hex"
"fmt"
"net"
"strconv"
@ -17,18 +19,6 @@ import (
// buildConfiguration fills the config template with the given instances
func (p *Provider) buildConfiguration(instances []ecsInstance) (*types.Configuration, error) {
services := make(map[string][]ecsInstance)
for _, instance := range instances {
backendName := getBackendName(instance)
if p.filterInstance(instance) {
if serviceInstances, ok := services[backendName]; ok {
services[backendName] = append(serviceInstances, instance)
} else {
services[backendName] = []ecsInstance{instance}
}
}
}
var ecsFuncMap = template.FuncMap{
// Backend functions
"getHost": getHost,
@ -43,6 +33,7 @@ func (p *Provider) buildConfiguration(instances []ecsInstance) (*types.Configura
// Frontend functions
"filterFrontends": filterFrontends,
"getFrontendRule": p.getFrontendRule,
"getFrontendName": p.getFrontendName,
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
"getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
@ -56,6 +47,25 @@ func (p *Provider) buildConfiguration(instances []ecsInstance) (*types.Configura
"getWhiteList": label.GetWhiteList,
}
services := make(map[string][]ecsInstance)
for _, instance := range instances {
segmentProperties := label.ExtractTraefikLabels(instance.TraefikLabels)
for segmentName, labels := range segmentProperties {
instance.SegmentLabels = labels
instance.SegmentName = segmentName
backendName := getBackendName(instance)
if p.filterInstance(instance) {
if serviceInstances, ok := services[backendName]; ok {
services[backendName] = append(serviceInstances, instance)
} else {
services[backendName] = []ecsInstance{instance}
}
}
}
}
return p.GetConfiguration("templates/ecs.tmpl", ecsFuncMap, struct {
Services map[string][]ecsInstance
}{
@ -101,25 +111,61 @@ func (p *Provider) filterInstance(i ecsInstance) bool {
}
func getBackendName(i ecsInstance) string {
if value := label.GetStringValue(i.TraefikLabels, label.TraefikBackend, ""); len(value) > 0 {
return value
if len(i.SegmentName) > 0 {
return getSegmentBackendName(i)
}
return i.Name
return getDefaultBackendName(i)
}
func getSegmentBackendName(i ecsInstance) string {
if value := label.GetStringValue(i.SegmentLabels, label.TraefikBackend, ""); len(value) > 0 {
return provider.Normalize(i.Name + "-" + value)
}
return provider.Normalize(i.Name + "-" + i.SegmentName)
}
func getDefaultBackendName(i ecsInstance) string {
if value := label.GetStringValue(i.SegmentLabels, label.TraefikBackend, ""); len(value) != 0 {
return provider.Normalize(value)
}
return provider.Normalize(i.Name)
}
func (p *Provider) getFrontendRule(i ecsInstance) string {
domain := label.GetStringValue(i.TraefikLabels, label.TraefikDomain, p.Domain)
if value := label.GetStringValue(i.SegmentLabels, label.TraefikFrontendRule, ""); len(value) != 0 {
return value
}
domain := label.GetStringValue(i.SegmentLabels, label.TraefikDomain, p.Domain)
defaultRule := "Host:" + strings.ToLower(strings.Replace(i.Name, "_", "-", -1)) + "." + domain
return label.GetStringValue(i.TraefikLabels, label.TraefikFrontendRule, defaultRule)
}
func (p *Provider) getFrontendName(instance ecsInstance) string {
name := getBackendName(instance)
if len(instance.SegmentName) > 0 {
name = instance.SegmentName + "-" + name
}
return provider.Normalize(name)
}
func getHost(i ecsInstance) string {
return i.machine.privateIP
}
func getPort(i ecsInstance) string {
if value := label.GetStringValue(i.TraefikLabels, label.TraefikPort, ""); len(value) > 0 {
value := label.GetStringValue(i.SegmentLabels, label.TraefikPort, "")
if len(value) == 0 {
value = label.GetStringValue(i.TraefikLabels, label.TraefikPort, "")
}
if len(value) > 0 {
port, err := strconv.ParseInt(value, 10, 64)
if err == nil {
for _, mapping := range i.machine.ports {
@ -138,6 +184,10 @@ func filterFrontends(instances []ecsInstance) []ecsInstance {
return fun.Filter(func(i ecsInstance) bool {
backendName := getBackendName(i)
if len(i.SegmentName) > 0 {
backendName = backendName + "-" + i.SegmentName
}
_, found := byName[backendName]
if !found {
byName[backendName] = struct{}{}
@ -154,14 +204,21 @@ func getServers(instances []ecsInstance) map[string]types.Server {
servers = make(map[string]types.Server)
}
protocol := label.GetStringValue(instance.TraefikLabels, label.TraefikProtocol, label.DefaultProtocol)
protocol := label.GetStringValue(instance.SegmentLabels, label.TraefikProtocol, label.DefaultProtocol)
host := getHost(instance)
port := getPort(instance)
serverName := provider.Normalize(fmt.Sprintf("server-%s-%s", instance.Name, instance.ID))
serverURL := fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(host, port))
serverName := getServerName(instance, serverURL)
if _, exist := servers[serverName]; exist {
log.Debugf("Skipping server %q with the same URL.", serverName)
continue
}
servers[serverName] = types.Server{
URL: fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(host, port)),
Weight: label.GetIntValue(instance.TraefikLabels, label.TraefikWeight, label.DefaultWeight),
URL: serverURL,
Weight: label.GetIntValue(instance.SegmentLabels, label.TraefikWeight, label.DefaultWeight),
}
}
@ -171,3 +228,18 @@ func getServers(instances []ecsInstance) map[string]types.Server {
func isEnabled(i ecsInstance, exposedByDefault bool) bool {
return label.GetBoolValue(i.TraefikLabels, label.TraefikEnable, exposedByDefault)
}
func getServerName(instance ecsInstance, url string) string {
hash := md5.New()
_, err := hash.Write([]byte(url))
if err != nil {
// Impossible case
log.Errorf("Fail to hash server URL %q", url)
}
if len(instance.SegmentName) > 0 {
return provider.Normalize(fmt.Sprintf("server-%s-%s-%s", instance.Name, instance.ID, hex.EncodeToString(hash.Sum(nil))))
}
return provider.Normalize(fmt.Sprintf("server-%s-%s", instance.Name, instance.ID))
}

View file

@ -0,0 +1,852 @@
package ecs
import (
"testing"
"time"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/containous/flaeg/parse"
"github.com/containous/traefik/provider/label"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSegmentBuildConfiguration(t *testing.T) {
testCases := []struct {
desc string
instanceInfo []ecsInstance
expectedFrontends map[string]*types.Frontend
expectedBackends map[string]*types.Backend
}{
{
desc: "when no container",
instanceInfo: []ecsInstance{},
expectedFrontends: map[string]*types.Frontend{},
expectedBackends: map[string]*types.Backend{},
},
{
desc: "simple configuration",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.ecs.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-123456789abc-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "auth basic",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicRemoveHeader: "true",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.ecs.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
RemoveHeader: true,
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-123456789abc-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "auth basic backward compatibility",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.ecs.localhost",
},
},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-123456789abc-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "auth digest",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestRemoveHeader: "true",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.ecs.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Digest: &types.Digest{
RemoveHeader: true,
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-123456789abc-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "auth forward",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("foo"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.frontend.entryPoints": "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardAddress: "auth.server",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTrustForwardHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCa: "ca.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCaOptional: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCert: "server.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSKey: "server.key",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSInsecureSkipVerify: "true",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
PassHostHeader: true,
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.ecs.localhost",
},
},
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Forward: &types.Forward{
Address: "auth.server",
TrustForwardHeader: true,
TLS: &types.ClientTLS{
CA: "ca.crt",
CAOptional: true,
Cert: "server.crt",
Key: "server.key",
InsecureSkipVerify: true,
},
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-123456789abc-863563a2e23c95502862016417ee95ea": {
URL: "http://127.0.0.1:2503",
Weight: label.DefaultWeight,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "when all labels are set",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("foo"),
labels(map[string]string{
label.Prefix + "sauternes." + label.SuffixPort: "666",
label.Prefix + "sauternes." + label.SuffixProtocol: "https",
label.Prefix + "sauternes." + label.SuffixWeight: "12",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicRemoveHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasicUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestRemoveHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsers: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendAuthDigestUsersFile: ".htpasswd",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardAddress: "auth.server",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTrustForwardHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCa: "ca.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCaOptional: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSCert: "server.crt",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSKey: "server.key",
label.Prefix + "sauternes." + label.SuffixFrontendAuthForwardTLSInsecureSkipVerify: "true",
label.Prefix + "sauternes." + label.SuffixFrontendAuthHeaderField: "X-WebAuth-User",
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
label.Prefix + "sauternes." + label.SuffixFrontendEntryPoints: "http,https",
label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendPassTLSCert: "true",
label.Prefix + "sauternes." + label.SuffixFrontendPriority: "666",
label.Prefix + "sauternes." + label.SuffixFrontendRedirectEntryPoint: "https",
label.Prefix + "sauternes." + label.SuffixFrontendRedirectRegex: "nope",
label.Prefix + "sauternes." + label.SuffixFrontendRedirectReplacement: "nope",
label.Prefix + "sauternes." + label.SuffixFrontendRedirectPermanent: "true",
label.Prefix + "sauternes." + label.SuffixFrontendWhiteListSourceRange: "10.10.10.10",
label.Prefix + "sauternes." + label.SuffixFrontendWhiteListIPStrategyExcludedIPS: "10.10.10.10,10.10.10.11",
label.Prefix + "sauternes." + label.SuffixFrontendWhiteListIPStrategyDepth: "5",
label.Prefix + "sauternes." + label.SuffixFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
label.Prefix + "sauternes." + label.SuffixFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSSLProxyHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersAllowedHosts: "foo,bar,bor",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersHostsProxyHeaders: "foo,bar,bor",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSSLHost: "foo",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersCustomFrameOptionsValue: "foo",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersContentSecurityPolicy: "foo",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersPublicKey: "foo",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersReferrerPolicy: "foo",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersCustomBrowserXSSValue: "foo",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSTSSeconds: "666",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSSLForceHost: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSSLRedirect: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSSLTemporaryRedirect: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSTSIncludeSubdomains: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersSTSPreload: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersForceSTSHeader: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersFrameDeny: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersContentTypeNosniff: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersBrowserXSSFilter: "true",
label.Prefix + "sauternes." + label.SuffixFrontendHeadersIsDevelopment: "true",
label.Prefix + "sauternes." + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: "404",
label.Prefix + "sauternes." + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: "foobar",
label.Prefix + "sauternes." + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: "foo_query",
label.Prefix + "sauternes." + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: "500,600",
label.Prefix + "sauternes." + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: "foobar",
label.Prefix + "sauternes." + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: "bar_query",
label.Prefix + "sauternes." + label.SuffixFrontendRateLimitExtractorFunc: "client.ip",
label.Prefix + "sauternes." + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: "6",
label.Prefix + "sauternes." + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: "12",
label.Prefix + "sauternes." + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: "18",
label.Prefix + "sauternes." + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: "3",
label.Prefix + "sauternes." + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: "6",
label.Prefix + "sauternes." + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: "9",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 666),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-foo-sauternes": {
Backend: "backend-foo-sauternes",
EntryPoints: []string{
"http",
"https",
},
PassHostHeader: true,
PassTLSCert: true,
Priority: 666,
Auth: &types.Auth{
HeaderField: "X-WebAuth-User",
Basic: &types.Basic{
RemoveHeader: true,
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
UsersFile: ".htpasswd",
},
},
WhiteList: &types.WhiteList{
SourceRange: []string{"10.10.10.10"},
IPStrategy: &types.IPStrategy{
Depth: 5,
ExcludedIPs: []string{"10.10.10.10", "10.10.10.11"},
},
},
Headers: &types.Headers{
CustomRequestHeaders: map[string]string{
"Access-Control-Allow-Methods": "POST,GET,OPTIONS",
"Content-Type": "application/json; charset=utf-8",
},
CustomResponseHeaders: map[string]string{
"Access-Control-Allow-Methods": "POST,GET,OPTIONS",
"Content-Type": "application/json; charset=utf-8",
},
AllowedHosts: []string{
"foo",
"bar",
"bor",
},
HostsProxyHeaders: []string{
"foo",
"bar",
"bor",
},
SSLRedirect: true,
SSLTemporaryRedirect: true,
SSLForceHost: true,
SSLHost: "foo",
SSLProxyHeaders: map[string]string{
"Access-Control-Allow-Methods": "POST,GET,OPTIONS",
"Content-Type": "application/json; charset=utf-8",
},
STSSeconds: 666,
STSIncludeSubdomains: true,
STSPreload: true,
ForceSTSHeader: true,
FrameDeny: true,
CustomFrameOptionsValue: "foo",
ContentTypeNosniff: true,
BrowserXSSFilter: true,
CustomBrowserXSSValue: "foo",
ContentSecurityPolicy: "foo",
PublicKey: "foo",
ReferrerPolicy: "foo",
IsDevelopment: true,
},
Errors: map[string]*types.ErrorPage{
"foo": {
Status: []string{"404"},
Query: "foo_query",
Backend: "backend-foobar",
},
"bar": {
Status: []string{"500", "600"},
Query: "bar_query",
Backend: "backend-foobar",
},
},
RateLimit: &types.RateLimit{
ExtractorFunc: "client.ip",
RateSet: map[string]*types.Rate{
"foo": {
Period: parse.Duration(6 * time.Second),
Average: 12,
Burst: 18,
},
"bar": {
Period: parse.Duration(3 * time.Second),
Average: 6,
Burst: 9,
},
},
},
Redirect: &types.Redirect{
EntryPoint: "https",
Regex: "",
Replacement: "",
Permanent: true,
},
Routes: map[string]types.Route{
"route-frontend-sauternes-foo-sauternes": {
Rule: "Host:foo.ecs.localhost",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-foo-sauternes": {
Servers: map[string]types.Server{
"server-foo-123456789abc-7f6444e0dff3330c8b0ad2bbbd383b0f": {
URL: "https://127.0.0.1:666",
Weight: 12,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "several containers",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("test1"),
labels(map[string]string{
"traefik.sauternes.port": "2503",
"traefik.sauternes.protocol": "https",
"traefik.sauternes.weight": "80",
"traefik.sauternes.backend": "foobar",
"traefik.sauternes.frontend.passHostHeader": "false",
"traefik.sauternes.frontend.rule": "Path:/mypath",
"traefik.sauternes.frontend.priority": "5000",
"traefik.sauternes.frontend.entryPoints": "http,https,ws",
"traefik.sauternes.frontend.auth.basic": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
"traefik.sauternes.frontend.redirect.entryPoint": "https",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
),
),
),
instance(
ID("abc987654321"),
name("test2"),
labels(map[string]string{
"traefik.anothersauternes.port": "8079",
"traefik.anothersauternes.weight": "33",
"traefik.anothersauternes.frontend.rule": "Path:/anotherpath",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.2"),
mPorts(
mPort(80, 8079),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-test1-foobar": {
Backend: "backend-test1-foobar",
PassHostHeader: false,
Priority: 5000,
EntryPoints: []string{"http", "https", "ws"},
Auth: &types.Auth{
Basic: &types.Basic{
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
},
},
Redirect: &types.Redirect{
EntryPoint: "https",
},
Routes: map[string]types.Route{
"route-frontend-sauternes-test1-foobar": {
Rule: "Path:/mypath",
},
},
},
"frontend-anothersauternes-test2-anothersauternes": {
Backend: "backend-test2-anothersauternes",
PassHostHeader: true,
EntryPoints: []string{},
Routes: map[string]types.Route{
"route-frontend-anothersauternes-test2-anothersauternes": {
Rule: "Path:/anotherpath",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test1-foobar": {
Servers: map[string]types.Server{
"server-test1-123456789abc-79533a101142718f0fdf84c42593c41e": {
URL: "https://127.0.0.1:2503",
Weight: 80,
},
},
CircuitBreaker: nil,
},
"backend-test2-anothersauternes": {
Servers: map[string]types.Server{
"server-test2-abc987654321-045e3e4aa5a744a325c099b803700a93": {
URL: "http://127.0.0.2:8079",
Weight: 33,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "several segments with the same backend name and same port",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("test1"),
labels(map[string]string{
"traefik.port": "2503",
"traefik.protocol": "https",
"traefik.weight": "80",
"traefik.frontend.entryPoints": "http,https",
"traefik.frontend.redirect.entryPoint": "https",
"traefik.sauternes.backend": "foobar",
"traefik.sauternes.frontend.rule": "Path:/sauternes",
"traefik.sauternes.frontend.priority": "5000",
"traefik.arbois.backend": "foobar",
"traefik.arbois.frontend.rule": "Path:/arbois",
"traefik.arbois.frontend.priority": "3000",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-test1-foobar": {
Backend: "backend-test1-foobar",
PassHostHeader: true,
Priority: 5000,
EntryPoints: []string{"http", "https"},
Redirect: &types.Redirect{
EntryPoint: "https",
},
Routes: map[string]types.Route{
"route-frontend-sauternes-test1-foobar": {
Rule: "Path:/sauternes",
},
},
},
"frontend-arbois-test1-foobar": {
Backend: "backend-test1-foobar",
PassHostHeader: true,
Priority: 3000,
EntryPoints: []string{"http", "https"},
Redirect: &types.Redirect{
EntryPoint: "https",
},
Routes: map[string]types.Route{
"route-frontend-arbois-test1-foobar": {
Rule: "Path:/arbois",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test1-foobar": {
Servers: map[string]types.Server{
"server-test1-123456789abc-79533a101142718f0fdf84c42593c41e": {
URL: "https://127.0.0.1:2503",
Weight: 80,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "several segments with the same backend name and different port (wrong behavior)",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("test1"),
labels(map[string]string{
"traefik.protocol": "https",
"traefik.frontend.entryPoints": "http,https",
"traefik.frontend.redirect.entryPoint": "https",
"traefik.sauternes.port": "2503",
"traefik.sauternes.weight": "80",
"traefik.sauternes.backend": "foobar",
"traefik.sauternes.frontend.rule": "Path:/sauternes",
"traefik.sauternes.frontend.priority": "5000",
"traefik.arbois.port": "2504",
"traefik.arbois.weight": "90",
"traefik.arbois.backend": "foobar",
"traefik.arbois.frontend.rule": "Path:/arbois",
"traefik.arbois.frontend.priority": "3000",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
mPort(80, 2504),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-test1-foobar": {
Backend: "backend-test1-foobar",
PassHostHeader: true,
Priority: 5000,
EntryPoints: []string{"http", "https"},
Redirect: &types.Redirect{
EntryPoint: "https",
},
Routes: map[string]types.Route{
"route-frontend-sauternes-test1-foobar": {
Rule: "Path:/sauternes",
},
},
},
"frontend-arbois-test1-foobar": {
Backend: "backend-test1-foobar",
PassHostHeader: true,
Priority: 3000,
EntryPoints: []string{"http", "https"},
Redirect: &types.Redirect{
EntryPoint: "https",
},
Routes: map[string]types.Route{
"route-frontend-arbois-test1-foobar": {
Rule: "Path:/arbois",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test1-foobar": {
Servers: map[string]types.Server{
"server-test1-123456789abc-79533a101142718f0fdf84c42593c41e": {
URL: "https://127.0.0.1:2503",
Weight: 80,
},
"server-test1-123456789abc-315a41140f1bd825b066e39686c18482": {
URL: "https://127.0.0.1:2504",
Weight: 90,
},
},
CircuitBreaker: nil,
},
},
},
{
desc: "several segments with the same backend name and different port binding",
instanceInfo: []ecsInstance{
instance(
ID("123456789abc"),
name("test1"),
labels(map[string]string{
"traefik.protocol": "https",
"traefik.frontend.entryPoints": "http,https",
"traefik.frontend.redirect.entryPoint": "https",
"traefik.sauternes.port": "2503",
"traefik.sauternes.weight": "80",
"traefik.sauternes.backend": "foobar",
"traefik.sauternes.frontend.rule": "Path:/sauternes",
"traefik.sauternes.frontend.priority": "5000",
"traefik.arbois.port": "8080",
"traefik.arbois.weight": "90",
"traefik.arbois.backend": "foobar",
"traefik.arbois.frontend.rule": "Path:/arbois",
"traefik.arbois.frontend.priority": "3000",
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("127.0.0.1"),
mPorts(
mPort(80, 2503),
mPort(8080, 2504),
),
),
),
},
expectedFrontends: map[string]*types.Frontend{
"frontend-sauternes-test1-foobar": {
Backend: "backend-test1-foobar",
PassHostHeader: true,
Priority: 5000,
EntryPoints: []string{"http", "https"},
Redirect: &types.Redirect{
EntryPoint: "https",
},
Routes: map[string]types.Route{
"route-frontend-sauternes-test1-foobar": {
Rule: "Path:/sauternes",
},
},
},
"frontend-arbois-test1-foobar": {
Backend: "backend-test1-foobar",
PassHostHeader: true,
Priority: 3000,
EntryPoints: []string{"http", "https"},
Redirect: &types.Redirect{
EntryPoint: "https",
},
Routes: map[string]types.Route{
"route-frontend-arbois-test1-foobar": {
Rule: "Path:/arbois",
},
},
},
},
expectedBackends: map[string]*types.Backend{
"backend-test1-foobar": {
Servers: map[string]types.Server{
"server-test1-123456789abc-79533a101142718f0fdf84c42593c41e": {
URL: "https://127.0.0.1:2503",
Weight: 80,
},
"server-test1-123456789abc-315a41140f1bd825b066e39686c18482": {
URL: "https://127.0.0.1:2504",
Weight: 90,
},
},
CircuitBreaker: nil,
},
},
},
}
provider := &Provider{
Domain: "ecs.localhost",
ExposedByDefault: true,
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
actualConfig, err := provider.buildConfiguration(test.instanceInfo)
assert.NoError(t, err)
require.NotNil(t, actualConfig, "actualConfig")
assert.EqualValues(t, test.expectedBackends, actualConfig.Backends)
assert.EqualValues(t, test.expectedFrontends, actualConfig.Frontends)
})
}
}

View file

@ -23,18 +23,18 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "config parsed successfully",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{},
},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
instance(
name("instance"),
ID("1"),
dockerLabels(map[string]*string{}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
@ -63,20 +63,21 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "config parsed successfully with health check labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckInterval: aws.String("1s"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
instance(
name("instance"),
ID("1"),
dockerLabels(map[string]*string{
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckInterval: aws.String("1s"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
@ -109,22 +110,23 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "config parsed successfully with basic auth labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
instance(
name("instance"),
ID("1"),
dockerLabels(map[string]*string{
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
@ -162,19 +164,20 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "config parsed successfully with basic auth (backward compatibility) labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
instance(
name("instance"),
ID("1"),
dockerLabels(map[string]*string{
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
@ -209,22 +212,23 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "config parsed successfully with digest auth labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
instance(
name("instance"),
ID("1"),
dockerLabels(map[string]*string{
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
@ -262,25 +266,26 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "config parsed successfully with forward auth labels",
instances: []ecsInstance{
{
Name: "instance",
ID: "1",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"), label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
instance(
name("instance"),
ID("1"),
dockerLabels(map[string]*string{
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"), label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
@ -323,108 +328,109 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "when all labels are set",
instances: []ecsInstance{
{
Name: "testing-instance",
ID: "6",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikPort: aws.String("666"),
label.TraefikProtocol: aws.String("https"),
label.TraefikWeight: aws.String("12"),
instance(
name("testing-instance"),
ID("6"),
dockerLabels(map[string]*string{
label.TraefikPort: aws.String("666"),
label.TraefikProtocol: aws.String("https"),
label.TraefikWeight: aws.String("12"),
label.TraefikBackend: aws.String("foobar"),
label.TraefikBackend: aws.String("foobar"),
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
label.TraefikBackendHealthCheckScheme: aws.String("http"),
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckPort: aws.String("880"),
label.TraefikBackendHealthCheckInterval: aws.String("6"),
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
label.TraefikBackendMaxConnAmount: aws.String("666"),
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
label.TraefikBackendHealthCheckScheme: aws.String("http"),
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckPort: aws.String("880"),
label.TraefikBackendHealthCheckInterval: aws.String("6"),
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
label.TraefikBackendMaxConnAmount: aws.String("666"),
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"),
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"),
label.TraefikFrontendPriority: aws.String("666"),
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
label.TraefikFrontendRedirectRegex: aws.String("nope"),
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
label.TraefikFrontendRedirectPermanent: aws.String("true"),
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
label.TraefikFrontendWhiteListIPStrategyExcludedIPS: aws.String("10.10.10.10,10.10.10.11"),
label.TraefikFrontendWhiteListIPStrategyDepth: aws.String("5"),
label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"),
label.TraefikFrontendPriority: aws.String("666"),
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
label.TraefikFrontendRedirectRegex: aws.String("nope"),
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
label.TraefikFrontendRedirectPermanent: aws.String("true"),
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
label.TraefikFrontendWhiteListIPStrategyExcludedIPS: aws.String("10.10.10.10,10.10.10.11"),
label.TraefikFrontendWhiteListIPStrategyDepth: aws.String("5"),
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendResponseHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendSSLProxyHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
label.TraefikFrontendSSLHost: aws.String("foo"),
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
label.TraefikFrontendPublicKey: aws.String("foo"),
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
label.TraefikFrontendSTSSeconds: aws.String("666"),
label.TraefikFrontendSSLForceHost: aws.String("true"),
label.TraefikFrontendSSLRedirect: aws.String("true"),
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
label.TraefikFrontendSTSPreload: aws.String("true"),
label.TraefikFrontendForceSTSHeader: aws.String("true"),
label.TraefikFrontendFrameDeny: aws.String("true"),
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
label.TraefikFrontendIsDevelopment: aws.String("true"),
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendResponseHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendSSLProxyHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
label.TraefikFrontendSSLHost: aws.String("foo"),
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
label.TraefikFrontendPublicKey: aws.String("foo"),
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
label.TraefikFrontendSTSSeconds: aws.String("666"),
label.TraefikFrontendSSLForceHost: aws.String("true"),
label.TraefikFrontendSSLRedirect: aws.String("true"),
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
label.TraefikFrontendSTSPreload: aws.String("true"),
label.TraefikFrontendForceSTSHeader: aws.String("true"),
label.TraefikFrontendFrameDeny: aws.String("true"),
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
label.TraefikFrontendIsDevelopment: aws.String("true"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: aws.String("500,600"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: aws.String("500,600"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: aws.String("12"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: aws.String("3"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: aws.String("12"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: aws.String("3"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{
@ -585,176 +591,178 @@ func TestBuildConfiguration(t *testing.T) {
{
desc: "Containers with same backend name",
instances: []ecsInstance{
{
Name: "testing-instance-v1",
ID: "6",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikPort: aws.String("666"),
label.TraefikProtocol: aws.String("https"),
label.TraefikWeight: aws.String("12"),
instance(
name("testing-instance-v1"),
ID("6"),
dockerLabels(map[string]*string{
label.TraefikPort: aws.String("666"),
label.TraefikProtocol: aws.String("https"),
label.TraefikWeight: aws.String("12"),
label.TraefikBackend: aws.String("foobar"),
label.TraefikBackend: aws.String("foobar"),
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
label.TraefikBackendHealthCheckScheme: aws.String("http"),
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckPort: aws.String("880"),
label.TraefikBackendHealthCheckInterval: aws.String("6"),
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
label.TraefikBackendMaxConnAmount: aws.String("666"),
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
label.TraefikBackendHealthCheckScheme: aws.String("http"),
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckPort: aws.String("880"),
label.TraefikBackendHealthCheckInterval: aws.String("6"),
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
label.TraefikBackendMaxConnAmount: aws.String("666"),
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"),
label.TraefikFrontendPriority: aws.String("666"),
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
label.TraefikFrontendRedirectRegex: aws.String("nope"),
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
label.TraefikFrontendRedirectPermanent: aws.String("true"),
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"),
label.TraefikFrontendPriority: aws.String("666"),
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
label.TraefikFrontendRedirectRegex: aws.String("nope"),
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
label.TraefikFrontendRedirectPermanent: aws.String("true"),
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendResponseHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendSSLProxyHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
label.TraefikFrontendSSLHost: aws.String("foo"),
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
label.TraefikFrontendPublicKey: aws.String("foo"),
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
label.TraefikFrontendSTSSeconds: aws.String("666"),
label.TraefikFrontendSSLForceHost: aws.String("true"),
label.TraefikFrontendSSLRedirect: aws.String("true"),
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
label.TraefikFrontendSTSPreload: aws.String("true"),
label.TraefikFrontendForceSTSHeader: aws.String("true"),
label.TraefikFrontendFrameDeny: aws.String("true"),
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
label.TraefikFrontendIsDevelopment: aws.String("true"),
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendResponseHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendSSLProxyHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
label.TraefikFrontendSSLHost: aws.String("foo"),
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
label.TraefikFrontendPublicKey: aws.String("foo"),
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
label.TraefikFrontendSTSSeconds: aws.String("666"),
label.TraefikFrontendSSLForceHost: aws.String("true"),
label.TraefikFrontendSSLRedirect: aws.String("true"),
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
label.TraefikFrontendSTSPreload: aws.String("true"),
label.TraefikFrontendForceSTSHeader: aws.String("true"),
label.TraefikFrontendFrameDeny: aws.String("true"),
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
label.TraefikFrontendIsDevelopment: aws.String("true"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: aws.String("500,600"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: aws.String("500,600"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: aws.String("12"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: aws.String("3"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.0.0.1",
ports: []portMapping{{hostPort: 1337}},
},
},
{
Name: "testing-instance-v2",
ID: "6",
containerDefinition: &ecs.ContainerDefinition{
DockerLabels: map[string]*string{
label.TraefikPort: aws.String("555"),
label.TraefikProtocol: aws.String("https"),
label.TraefikWeight: aws.String("15"),
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: aws.String("12"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: aws.String("3"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.0.0.1"),
mPorts(
mPort(0, 1337),
),
),
),
instance(
name("testing-instance-v2"),
ID("6"),
dockerLabels(map[string]*string{
label.TraefikPort: aws.String("555"),
label.TraefikProtocol: aws.String("https"),
label.TraefikWeight: aws.String("15"),
label.TraefikBackend: aws.String("foobar"),
label.TraefikBackend: aws.String("foobar"),
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
label.TraefikBackendHealthCheckScheme: aws.String("http"),
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckPort: aws.String("880"),
label.TraefikBackendHealthCheckInterval: aws.String("6"),
label.TraefikBackendHealthCheckHostname: aws.String("bar.com"),
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
label.TraefikBackendMaxConnAmount: aws.String("666"),
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
label.TraefikBackendHealthCheckScheme: aws.String("http"),
label.TraefikBackendHealthCheckPath: aws.String("/health"),
label.TraefikBackendHealthCheckPort: aws.String("880"),
label.TraefikBackendHealthCheckInterval: aws.String("6"),
label.TraefikBackendHealthCheckHostname: aws.String("bar.com"),
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
label.TraefikBackendMaxConnAmount: aws.String("666"),
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"),
label.TraefikFrontendPriority: aws.String("666"),
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
label.TraefikFrontendRedirectRegex: aws.String("nope"),
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
label.TraefikFrontendRedirectPermanent: aws.String("true"),
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
label.TraefikFrontendEntryPoints: aws.String("http,https"),
label.TraefikFrontendPassHostHeader: aws.String("true"),
label.TraefikFrontendPassTLSCert: aws.String("true"),
label.TraefikFrontendPriority: aws.String("666"),
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
label.TraefikFrontendRedirectRegex: aws.String("nope"),
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
label.TraefikFrontendRedirectPermanent: aws.String("true"),
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendResponseHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendSSLProxyHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
label.TraefikFrontendSSLHost: aws.String("foo"),
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
label.TraefikFrontendPublicKey: aws.String("foo"),
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
label.TraefikFrontendSTSSeconds: aws.String("666"),
label.TraefikFrontendSSLForceHost: aws.String("true"),
label.TraefikFrontendSSLRedirect: aws.String("true"),
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
label.TraefikFrontendSTSPreload: aws.String("true"),
label.TraefikFrontendForceSTSHeader: aws.String("true"),
label.TraefikFrontendFrameDeny: aws.String("true"),
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
label.TraefikFrontendIsDevelopment: aws.String("true"),
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendResponseHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendSSLProxyHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
label.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
label.TraefikFrontendSSLHost: aws.String("foo"),
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
label.TraefikFrontendPublicKey: aws.String("foo"),
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
label.TraefikFrontendSTSSeconds: aws.String("666"),
label.TraefikFrontendSSLForceHost: aws.String("true"),
label.TraefikFrontendSSLRedirect: aws.String("true"),
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
label.TraefikFrontendSTSPreload: aws.String("true"),
label.TraefikFrontendForceSTSHeader: aws.String("true"),
label.TraefikFrontendFrameDeny: aws.String("true"),
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
label.TraefikFrontendIsDevelopment: aws.String("true"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: aws.String("500,600"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: aws.String("500,600"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: aws.String("12"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: aws.String("3"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
}},
machine: &machine{
state: ec2.InstanceStateNameRunning,
privateIP: "10.2.2.1",
ports: []portMapping{{hostPort: 1337}},
},
},
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: aws.String("12"),
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: aws.String("3"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
}),
iMachine(
mState(ec2.InstanceStateNameRunning),
mPrivateIP("10.2.2.1"),
mPorts(
mPort(0, 1337),
),
),
),
},
expected: &types.Configuration{
Backends: map[string]*types.Backend{

View file

@ -45,6 +45,8 @@ type ecsInstance struct {
containerDefinition *ecs.ContainerDefinition
machine *machine
TraefikLabels map[string]string
SegmentLabels map[string]string
SegmentName string
}
type portMapping struct {