Add segment support for ECS
This commit is contained in:
parent
ef753838e7
commit
a302731cd1
9 changed files with 1559 additions and 438 deletions
|
@ -887,13 +887,13 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{range $serviceName, $instances := .Services }}
|
{{range $serviceName, $instances := .Services }}
|
||||||
{{ $firstInstance := index $instances 0 }}
|
{{ $firstInstance := index $instances 0 }}
|
||||||
|
|
||||||
{{ $circuitBreaker := getCircuitBreaker $firstInstance.TraefikLabels }}
|
{{ $circuitBreaker := getCircuitBreaker $firstInstance.SegmentLabels }}
|
||||||
{{if $circuitBreaker }}
|
{{if $circuitBreaker }}
|
||||||
[backends."backend-{{ $serviceName }}".circuitBreaker]
|
[backends."backend-{{ $serviceName }}".circuitBreaker]
|
||||||
expression = "{{ $circuitBreaker.Expression }}"
|
expression = "{{ $circuitBreaker.Expression }}"
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $loadBalancer := getLoadBalancer $firstInstance.TraefikLabels }}
|
{{ $loadBalancer := getLoadBalancer $firstInstance.SegmentLabels }}
|
||||||
{{if $loadBalancer }}
|
{{if $loadBalancer }}
|
||||||
[backends."backend-{{ $serviceName }}".loadBalancer]
|
[backends."backend-{{ $serviceName }}".loadBalancer]
|
||||||
method = "{{ $loadBalancer.Method }}"
|
method = "{{ $loadBalancer.Method }}"
|
||||||
|
@ -904,14 +904,14 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $maxConn := getMaxConn $firstInstance.TraefikLabels }}
|
{{ $maxConn := getMaxConn $firstInstance.SegmentLabels }}
|
||||||
{{if $maxConn }}
|
{{if $maxConn }}
|
||||||
[backends."backend-{{ $serviceName }}".maxConn]
|
[backends."backend-{{ $serviceName }}".maxConn]
|
||||||
extractorFunc = "{{ $maxConn.ExtractorFunc }}"
|
extractorFunc = "{{ $maxConn.ExtractorFunc }}"
|
||||||
amount = {{ $maxConn.Amount }}
|
amount = {{ $maxConn.Amount }}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $healthCheck := getHealthCheck $firstInstance.TraefikLabels }}
|
{{ $healthCheck := getHealthCheck $firstInstance.SegmentLabels }}
|
||||||
{{if $healthCheck }}
|
{{if $healthCheck }}
|
||||||
[backends."backend-{{ $serviceName }}".healthCheck]
|
[backends."backend-{{ $serviceName }}".healthCheck]
|
||||||
scheme = "{{ $healthCheck.Scheme }}"
|
scheme = "{{ $healthCheck.Scheme }}"
|
||||||
|
@ -927,7 +927,7 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $buffering := getBuffering $firstInstance.TraefikLabels }}
|
{{ $buffering := getBuffering $firstInstance.SegmentLabels }}
|
||||||
{{if $buffering }}
|
{{if $buffering }}
|
||||||
[backends."backend-{{ $serviceName }}".buffering]
|
[backends."backend-{{ $serviceName }}".buffering]
|
||||||
maxRequestBodyBytes = {{ $buffering.MaxRequestBodyBytes }}
|
maxRequestBodyBytes = {{ $buffering.MaxRequestBodyBytes }}
|
||||||
|
@ -949,28 +949,30 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{range $serviceName, $instances := .Services }}
|
{{range $serviceName, $instances := .Services }}
|
||||||
{{range $instance := filterFrontends $instances }}
|
{{range $instance := filterFrontends $instances }}
|
||||||
|
|
||||||
[frontends."frontend-{{ $serviceName }}"]
|
{{ $frontendName := getFrontendName $instance }}
|
||||||
backend = "backend-{{ $serviceName }}"
|
|
||||||
priority = {{ getPriority $instance.TraefikLabels }}
|
|
||||||
passHostHeader = {{ getPassHostHeader $instance.TraefikLabels }}
|
|
||||||
passTLSCert = {{ getPassTLSCert $instance.TraefikLabels }}
|
|
||||||
|
|
||||||
entryPoints = [{{range getEntryPoints $instance.TraefikLabels }}
|
[frontends."frontend-{{ $frontendName }}"]
|
||||||
|
backend = "backend-{{ $serviceName }}"
|
||||||
|
priority = {{ getPriority $instance.SegmentLabels }}
|
||||||
|
passHostHeader = {{ getPassHostHeader $instance.SegmentLabels }}
|
||||||
|
passTLSCert = {{ getPassTLSCert $instance.SegmentLabels }}
|
||||||
|
|
||||||
|
entryPoints = [{{range getEntryPoints $instance.SegmentLabels }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
|
|
||||||
{{ $auth := getAuth $instance.TraefikLabels }}
|
{{ $auth := getAuth $instance.SegmentLabels }}
|
||||||
{{if $auth }}
|
{{if $auth }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth]
|
[frontends."frontend-{{ $frontendName }}".auth]
|
||||||
headerField = "{{ $auth.HeaderField }}"
|
headerField = "{{ $auth.HeaderField }}"
|
||||||
|
|
||||||
{{if $auth.Forward }}
|
{{if $auth.Forward }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.forward]
|
[frontends."frontend-{{ $frontendName }}".auth.forward]
|
||||||
address = "{{ $auth.Forward.Address }}"
|
address = "{{ $auth.Forward.Address }}"
|
||||||
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
|
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
|
||||||
|
|
||||||
{{if $auth.Forward.TLS }}
|
{{if $auth.Forward.TLS }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.forward.tls]
|
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
|
||||||
ca = "{{ $auth.Forward.TLS.CA }}"
|
ca = "{{ $auth.Forward.TLS.CA }}"
|
||||||
caOptional = {{ $auth.Forward.TLS.CAOptional }}
|
caOptional = {{ $auth.Forward.TLS.CAOptional }}
|
||||||
cert = """{{ $auth.Forward.TLS.Cert }}"""
|
cert = """{{ $auth.Forward.TLS.Cert }}"""
|
||||||
|
@ -980,7 +982,7 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $auth.Basic }}
|
{{if $auth.Basic }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.basic]
|
[frontends."frontend-{{ $frontendName }}".auth.basic]
|
||||||
removeHeader = {{ $auth.Basic.RemoveHeader }}
|
removeHeader = {{ $auth.Basic.RemoveHeader }}
|
||||||
{{if $auth.Basic.Users }}
|
{{if $auth.Basic.Users }}
|
||||||
users = [{{range $auth.Basic.Users }}
|
users = [{{range $auth.Basic.Users }}
|
||||||
|
@ -991,7 +993,7 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $auth.Digest }}
|
{{if $auth.Digest }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.digest]
|
[frontends."frontend-{{ $frontendName }}".auth.digest]
|
||||||
removeHeader = {{ $auth.Digest.RemoveHeader }}
|
removeHeader = {{ $auth.Digest.RemoveHeader }}
|
||||||
{{if $auth.Digest.Users }}
|
{{if $auth.Digest.Users }}
|
||||||
users = [{{range $auth.Digest.Users }}
|
users = [{{range $auth.Digest.Users }}
|
||||||
|
@ -1002,29 +1004,29 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $whitelist := getWhiteList $instance.TraefikLabels }}
|
{{ $whitelist := getWhiteList $instance.SegmentLabels }}
|
||||||
{{if $whitelist }}
|
{{if $whitelist }}
|
||||||
[frontends."frontend-{{ $serviceName }}".whiteList]
|
[frontends."frontend-{{ $frontendName }}".whiteList]
|
||||||
sourceRange = [{{range $whitelist.SourceRange }}
|
sourceRange = [{{range $whitelist.SourceRange }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
useXForwardedFor = {{ $whitelist.UseXForwardedFor }}
|
useXForwardedFor = {{ $whitelist.UseXForwardedFor }}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $redirect := getRedirect $instance.TraefikLabels }}
|
{{ $redirect := getRedirect $instance.SegmentLabels }}
|
||||||
{{if $redirect }}
|
{{if $redirect }}
|
||||||
[frontends."frontend-{{ $serviceName }}".redirect]
|
[frontends."frontend-{{ $frontendName }}".redirect]
|
||||||
entryPoint = "{{ $redirect.EntryPoint }}"
|
entryPoint = "{{ $redirect.EntryPoint }}"
|
||||||
regex = "{{ $redirect.Regex }}"
|
regex = "{{ $redirect.Regex }}"
|
||||||
replacement = "{{ $redirect.Replacement }}"
|
replacement = "{{ $redirect.Replacement }}"
|
||||||
permanent = {{ $redirect.Permanent }}
|
permanent = {{ $redirect.Permanent }}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $errorPages := getErrorPages $instance.TraefikLabels }}
|
{{ $errorPages := getErrorPages $instance.SegmentLabels }}
|
||||||
{{if $errorPages }}
|
{{if $errorPages }}
|
||||||
[frontends."frontend-{{ $serviceName }}".errors]
|
[frontends."frontend-{{ $frontendName }}".errors]
|
||||||
{{range $pageName, $page := $errorPages }}
|
{{range $pageName, $page := $errorPages }}
|
||||||
[frontends."frontend-{{ $serviceName }}".errors."{{ $pageName }}"]
|
[frontends."frontend-{{ $frontendName }}".errors."{{ $pageName }}"]
|
||||||
status = [{{range $page.Status }}
|
status = [{{range $page.Status }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
|
@ -1033,22 +1035,22 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $rateLimit := getRateLimit $instance.TraefikLabels }}
|
{{ $rateLimit := getRateLimit $instance.SegmentLabels }}
|
||||||
{{if $rateLimit }}
|
{{if $rateLimit }}
|
||||||
[frontends."frontend-{{ $serviceName }}".rateLimit]
|
[frontends."frontend-{{ $frontendName }}".rateLimit]
|
||||||
extractorFunc = "{{ $rateLimit.ExtractorFunc }}"
|
extractorFunc = "{{ $rateLimit.ExtractorFunc }}"
|
||||||
[frontends."frontend-{{ $serviceName }}".rateLimit.rateSet]
|
[frontends."frontend-{{ $frontendName }}".rateLimit.rateSet]
|
||||||
{{ range $limitName, $limit := $rateLimit.RateSet }}
|
{{ range $limitName, $limit := $rateLimit.RateSet }}
|
||||||
[frontends."frontend-{{ $serviceName }}".rateLimit.rateSet."{{ $limitName }}"]
|
[frontends."frontend-{{ $frontendName }}".rateLimit.rateSet."{{ $limitName }}"]
|
||||||
period = "{{ $limit.Period }}"
|
period = "{{ $limit.Period }}"
|
||||||
average = {{ $limit.Average }}
|
average = {{ $limit.Average }}
|
||||||
burst = {{ $limit.Burst }}
|
burst = {{ $limit.Burst }}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $headers := getHeaders $instance.TraefikLabels }}
|
{{ $headers := getHeaders $instance.SegmentLabels }}
|
||||||
{{if $headers }}
|
{{if $headers }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers]
|
[frontends."frontend-{{ $frontendName }}".headers]
|
||||||
SSLRedirect = {{ $headers.SSLRedirect }}
|
SSLRedirect = {{ $headers.SSLRedirect }}
|
||||||
SSLTemporaryRedirect = {{ $headers.SSLTemporaryRedirect }}
|
SSLTemporaryRedirect = {{ $headers.SSLTemporaryRedirect }}
|
||||||
SSLHost = "{{ $headers.SSLHost }}"
|
SSLHost = "{{ $headers.SSLHost }}"
|
||||||
|
@ -1080,28 +1082,28 @@ var _templatesEcsTmpl = []byte(`[backends]
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $headers.CustomRequestHeaders }}
|
{{if $headers.CustomRequestHeaders }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers.customRequestHeaders]
|
[frontends."frontend-{{ $frontendName }}".headers.customRequestHeaders]
|
||||||
{{range $k, $v := $headers.CustomRequestHeaders }}
|
{{range $k, $v := $headers.CustomRequestHeaders }}
|
||||||
{{$k}} = "{{$v}}"
|
{{$k}} = "{{$v}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $headers.CustomResponseHeaders }}
|
{{if $headers.CustomResponseHeaders }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers.customResponseHeaders]
|
[frontends."frontend-{{ $frontendName }}".headers.customResponseHeaders]
|
||||||
{{range $k, $v := $headers.CustomResponseHeaders }}
|
{{range $k, $v := $headers.CustomResponseHeaders }}
|
||||||
{{$k}} = "{{$v}}"
|
{{$k}} = "{{$v}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $headers.SSLProxyHeaders }}
|
{{if $headers.SSLProxyHeaders }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers.SSLProxyHeaders]
|
[frontends."frontend-{{ $frontendName }}".headers.SSLProxyHeaders]
|
||||||
{{range $k, $v := $headers.SSLProxyHeaders }}
|
{{range $k, $v := $headers.SSLProxyHeaders }}
|
||||||
{{$k}} = "{{$v}}"
|
{{$k}} = "{{$v}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
[frontends."frontend-{{ $serviceName }}".routes."route-frontend-{{ $serviceName }}"]
|
[frontends."frontend-{{ $frontendName }}".routes."route-frontend-{{ $frontendName }}"]
|
||||||
rule = "{{ getFrontendRule $instance }}"
|
rule = "{{ getFrontendRule $instance }}"
|
||||||
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -228,3 +228,85 @@ Labels can be used on task containers to override default behaviour:
|
||||||
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
|
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
|
||||||
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
|
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
|
||||||
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
|
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
|
||||||
|
|
||||||
|
### Containers with Multiple Ports (segment labels)
|
||||||
|
|
||||||
|
Segment labels are used to define routes to an application exposing multiple ports.
|
||||||
|
A segment is a group of labels that apply to a port exposed by an application.
|
||||||
|
You can define as many segments as ports exposed in an application.
|
||||||
|
|
||||||
|
Segment labels override the default behavior.
|
||||||
|
|
||||||
|
| Label | Description |
|
||||||
|
|---------------------------------------------------------------------------|----------------------------------------------------------------|
|
||||||
|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
|
||||||
|
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
|
||||||
|
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
|
||||||
|
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
|
||||||
|
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com`| Same as `traefik.frontend.auth.forward.address` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true`| Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
|
||||||
|
| `traefik.<segment_name>.frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` |
|
||||||
|
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
|
||||||
|
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
|
||||||
|
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
|
||||||
|
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
|
||||||
|
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
|
||||||
|
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
|
||||||
|
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
|
||||||
|
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
|
||||||
|
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
|
||||||
|
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
|
||||||
|
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
|
||||||
|
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
|
||||||
|
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
|
||||||
|
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
|
||||||
|
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
|
||||||
|
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
|
||||||
|
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
|
||||||
|
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
|
||||||
|
|
||||||
|
#### Custom Headers
|
||||||
|
|
||||||
|
| Label | Description |
|
||||||
|
|----------------------------------------------------------------------|----------------------------------------------------------|
|
||||||
|
| `traefik.<segment_name>.frontend.headers.customRequestHeaders=EXPR ` | Same as `traefik.frontend.headers.customRequestHeaders` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.customResponseHeaders=EXPR` | Same as `traefik.frontend.headers.customResponseHeaders` |
|
||||||
|
|
||||||
|
#### Security Headers
|
||||||
|
|
||||||
|
| Label | Description |
|
||||||
|
|-------------------------------------------------------------------------|--------------------------------------------------------------|
|
||||||
|
| `traefik.<segment_name>.frontend.headers.allowedHosts=EXPR` | Same as `traefik.frontend.headers.allowedHosts` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.browserXSSFilter=true` | Same as `traefik.frontend.headers.browserXSSFilter` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.contentSecurityPolicy=VALUE` | Same as `traefik.frontend.headers.contentSecurityPolicy` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.contentTypeNosniff=true` | Same as `traefik.frontend.headers.contentTypeNosniff` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.customBrowserXSSValue=VALUE` | Same as `traefik.frontend.headers.customBrowserXSSValue` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.customFrameOptionsValue=VALUE` | Same as `traefik.frontend.headers.customFrameOptionsValue` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.forceSTSHeader=false` | Same as `traefik.frontend.headers.forceSTSHeader` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.frameDeny=false` | Same as `traefik.frontend.headers.frameDeny` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.hostsProxyHeaders=EXPR` | Same as `traefik.frontend.headers.hostsProxyHeaders` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.isDevelopment=false` | Same as `traefik.frontend.headers.isDevelopment` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.publicKey=VALUE` | Same as `traefik.frontend.headers.publicKey` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.referrerPolicy=VALUE` | Same as `traefik.frontend.headers.referrerPolicy` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.SSLRedirect=true` | Same as `traefik.frontend.headers.SSLRedirect` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.SSLTemporaryRedirect=true` | Same as `traefik.frontend.headers.SSLTemporaryRedirect` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.SSLHost=HOST` | Same as `traefik.frontend.headers.SSLHost` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.SSLForceHost=true` | Same as `traefik.frontend.headers.SSLForceHost` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.SSLProxyHeaders=EXPR` | Same as `traefik.frontend.headers.SSLProxyHeaders=EXPR` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.STSSeconds=315360000` | Same as `traefik.frontend.headers.STSSeconds=315360000` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.STSIncludeSubdomains=true` | Same as `traefik.frontend.headers.STSIncludeSubdomains=true` |
|
||||||
|
| `traefik.<segment_name>.frontend.headers.STSPreload=true` | Same as `traefik.frontend.headers.STSPreload=true` |
|
||||||
|
|
85
provider/ecs/builder_test.go
Normal file
85
provider/ecs/builder_test.go
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
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 mName(name string) func(*machine) {
|
||||||
|
return func(m *machine) {
|
||||||
|
m.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -17,18 +19,6 @@ import (
|
||||||
|
|
||||||
// buildConfiguration fills the config template with the given instances
|
// buildConfiguration fills the config template with the given instances
|
||||||
func (p *Provider) buildConfigurationV2(instances []ecsInstance) (*types.Configuration, error) {
|
func (p *Provider) buildConfigurationV2(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{
|
var ecsFuncMap = template.FuncMap{
|
||||||
// Backend functions
|
// Backend functions
|
||||||
"getHost": getHost,
|
"getHost": getHost,
|
||||||
|
@ -43,6 +33,7 @@ func (p *Provider) buildConfigurationV2(instances []ecsInstance) (*types.Configu
|
||||||
// Frontend functions
|
// Frontend functions
|
||||||
"filterFrontends": filterFrontends,
|
"filterFrontends": filterFrontends,
|
||||||
"getFrontendRule": p.getFrontendRule,
|
"getFrontendRule": p.getFrontendRule,
|
||||||
|
"getFrontendName": p.getFrontendName,
|
||||||
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
|
"getPassHostHeader": label.GetFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
|
||||||
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
"getPassTLSCert": label.GetFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||||
"getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
"getPriority": label.GetFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
||||||
|
@ -56,6 +47,25 @@ func (p *Provider) buildConfigurationV2(instances []ecsInstance) (*types.Configu
|
||||||
"getWhiteList": label.GetWhiteList,
|
"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 {
|
return p.GetConfiguration("templates/ecs.tmpl", ecsFuncMap, struct {
|
||||||
Services map[string][]ecsInstance
|
Services map[string][]ecsInstance
|
||||||
}{
|
}{
|
||||||
|
@ -101,25 +111,61 @@ func (p *Provider) filterInstance(i ecsInstance) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBackendName(i ecsInstance) string {
|
func getBackendName(i ecsInstance) string {
|
||||||
if value := label.GetStringValue(i.TraefikLabels, label.TraefikBackend, ""); len(value) > 0 {
|
if len(i.SegmentName) > 0 {
|
||||||
return value
|
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 {
|
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
|
defaultRule := "Host:" + strings.ToLower(strings.Replace(i.Name, "_", "-", -1)) + "." + domain
|
||||||
|
|
||||||
return label.GetStringValue(i.TraefikLabels, label.TraefikFrontendRule, defaultRule)
|
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 {
|
func getHost(i ecsInstance) string {
|
||||||
return i.machine.privateIP
|
return i.machine.privateIP
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPort(i ecsInstance) string {
|
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)
|
port, err := strconv.ParseInt(value, 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, mapping := range i.machine.ports {
|
for _, mapping := range i.machine.ports {
|
||||||
|
@ -138,6 +184,11 @@ func filterFrontends(instances []ecsInstance) []ecsInstance {
|
||||||
|
|
||||||
return fun.Filter(func(i ecsInstance) bool {
|
return fun.Filter(func(i ecsInstance) bool {
|
||||||
backendName := getBackendName(i)
|
backendName := getBackendName(i)
|
||||||
|
|
||||||
|
if len(i.SegmentName) > 0 {
|
||||||
|
backendName = backendName + "-" + i.SegmentName
|
||||||
|
}
|
||||||
|
|
||||||
_, found := byName[backendName]
|
_, found := byName[backendName]
|
||||||
if !found {
|
if !found {
|
||||||
byName[backendName] = struct{}{}
|
byName[backendName] = struct{}{}
|
||||||
|
@ -154,14 +205,21 @@ func getServers(instances []ecsInstance) map[string]types.Server {
|
||||||
servers = make(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)
|
host := getHost(instance)
|
||||||
port := getPort(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{
|
servers[serverName] = types.Server{
|
||||||
URL: fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(host, port)),
|
URL: serverURL,
|
||||||
Weight: label.GetIntValue(instance.TraefikLabels, label.TraefikWeight, label.DefaultWeight),
|
Weight: label.GetIntValue(instance.SegmentLabels, label.TraefikWeight, label.DefaultWeight),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,3 +229,18 @@ func getServers(instances []ecsInstance) map[string]types.Server {
|
||||||
func isEnabled(i ecsInstance, exposedByDefault bool) bool {
|
func isEnabled(i ecsInstance, exposedByDefault bool) bool {
|
||||||
return label.GetBoolValue(i.TraefikLabels, label.TraefikEnable, exposedByDefault)
|
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))
|
||||||
|
}
|
||||||
|
|
859
provider/ecs/config_segment_test.go
Normal file
859
provider/ecs/config_segment_test.go
Normal file
|
@ -0,0 +1,859 @@
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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.SuffixFrontendWhiteListUseXForwardedFor: "true",
|
||||||
|
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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"},
|
||||||
|
UseXForwardedFor: true,
|
||||||
|
},
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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(
|
||||||
|
mName("machine1"),
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,18 +23,18 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "config parsed successfully",
|
desc: "config parsed successfully",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "instance",
|
name("instance"),
|
||||||
ID: "1",
|
ID("1"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{}),
|
||||||
DockerLabels: map[string]*string{},
|
iMachine(
|
||||||
},
|
mState(ec2.InstanceStateNameRunning),
|
||||||
machine: &machine{
|
mPrivateIP("10.0.0.1"),
|
||||||
state: ec2.InstanceStateNameRunning,
|
mPorts(
|
||||||
privateIP: "10.0.0.1",
|
mPort(0, 1337),
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
),
|
||||||
},
|
),
|
||||||
},
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
@ -63,20 +63,21 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "config parsed successfully with health check labels",
|
desc: "config parsed successfully with health check labels",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "instance",
|
name("instance"),
|
||||||
ID: "1",
|
ID("1"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{
|
||||||
DockerLabels: map[string]*string{
|
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
||||||
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
label.TraefikBackendHealthCheckInterval: aws.String("1s"),
|
||||||
label.TraefikBackendHealthCheckInterval: aws.String("1s"),
|
}),
|
||||||
}},
|
iMachine(
|
||||||
machine: &machine{
|
mState(ec2.InstanceStateNameRunning),
|
||||||
state: ec2.InstanceStateNameRunning,
|
mPrivateIP("10.0.0.1"),
|
||||||
privateIP: "10.0.0.1",
|
mPorts(
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
@ -109,22 +110,23 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "config parsed successfully with basic auth labels",
|
desc: "config parsed successfully with basic auth labels",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "instance",
|
name("instance"),
|
||||||
ID: "1",
|
ID("1"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{
|
||||||
DockerLabels: map[string]*string{
|
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
|
||||||
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
|
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
|
||||||
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
|
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
||||||
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
}),
|
||||||
}},
|
iMachine(
|
||||||
machine: &machine{
|
mState(ec2.InstanceStateNameRunning),
|
||||||
state: ec2.InstanceStateNameRunning,
|
mPrivateIP("10.0.0.1"),
|
||||||
privateIP: "10.0.0.1",
|
mPorts(
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
@ -162,19 +164,20 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "config parsed successfully with basic auth (backward compatibility) labels",
|
desc: "config parsed successfully with basic auth (backward compatibility) labels",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "instance",
|
name("instance"),
|
||||||
ID: "1",
|
ID("1"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{
|
||||||
DockerLabels: map[string]*string{
|
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
}),
|
||||||
}},
|
iMachine(
|
||||||
machine: &machine{
|
mState(ec2.InstanceStateNameRunning),
|
||||||
state: ec2.InstanceStateNameRunning,
|
mPrivateIP("10.0.0.1"),
|
||||||
privateIP: "10.0.0.1",
|
mPorts(
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
@ -209,22 +212,23 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "config parsed successfully with digest auth labels",
|
desc: "config parsed successfully with digest auth labels",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "instance",
|
name("instance"),
|
||||||
ID: "1",
|
ID("1"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{
|
||||||
DockerLabels: map[string]*string{
|
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
|
||||||
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
|
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
|
||||||
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
|
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
||||||
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
}),
|
||||||
}},
|
iMachine(
|
||||||
machine: &machine{
|
mState(ec2.InstanceStateNameRunning),
|
||||||
state: ec2.InstanceStateNameRunning,
|
mPrivateIP("10.0.0.1"),
|
||||||
privateIP: "10.0.0.1",
|
mPorts(
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
@ -262,25 +266,26 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "config parsed successfully with forward auth labels",
|
desc: "config parsed successfully with forward auth labels",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "instance",
|
name("instance"),
|
||||||
ID: "1",
|
ID("1"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{
|
||||||
DockerLabels: map[string]*string{
|
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
|
||||||
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
|
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
|
||||||
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
|
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
|
||||||
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
|
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
|
||||||
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
|
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
|
||||||
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
|
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
|
||||||
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
|
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"), label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
||||||
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"), label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
}),
|
||||||
}},
|
iMachine(
|
||||||
machine: &machine{
|
mState(ec2.InstanceStateNameRunning),
|
||||||
state: ec2.InstanceStateNameRunning,
|
mPrivateIP("10.0.0.1"),
|
||||||
privateIP: "10.0.0.1",
|
mPorts(
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
@ -323,108 +328,109 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "when all labels are set",
|
desc: "when all labels are set",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "testing-instance",
|
name("testing-instance"),
|
||||||
ID: "6",
|
ID("6"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{
|
||||||
DockerLabels: map[string]*string{
|
label.TraefikPort: aws.String("666"),
|
||||||
label.TraefikPort: aws.String("666"),
|
label.TraefikProtocol: aws.String("https"),
|
||||||
label.TraefikProtocol: aws.String("https"),
|
label.TraefikWeight: aws.String("12"),
|
||||||
label.TraefikWeight: aws.String("12"),
|
|
||||||
|
|
||||||
label.TraefikBackend: aws.String("foobar"),
|
label.TraefikBackend: aws.String("foobar"),
|
||||||
|
|
||||||
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
|
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
|
||||||
label.TraefikBackendHealthCheckScheme: aws.String("http"),
|
label.TraefikBackendHealthCheckScheme: aws.String("http"),
|
||||||
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
||||||
label.TraefikBackendHealthCheckPort: aws.String("880"),
|
label.TraefikBackendHealthCheckPort: aws.String("880"),
|
||||||
label.TraefikBackendHealthCheckInterval: aws.String("6"),
|
label.TraefikBackendHealthCheckInterval: aws.String("6"),
|
||||||
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
|
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
|
||||||
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
||||||
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
||||||
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
||||||
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
||||||
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
||||||
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
||||||
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
|
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
|
||||||
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
|
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
|
||||||
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
|
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
|
||||||
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
|
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
|
||||||
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
|
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
|
||||||
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
|
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
|
||||||
|
|
||||||
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
|
label.TraefikFrontendAuthBasicRemoveHeader: aws.String("true"),
|
||||||
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
|
label.TraefikFrontendAuthBasicUsersFile: aws.String(".htpasswd"),
|
||||||
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
|
label.TraefikFrontendAuthDigestRemoveHeader: aws.String("true"),
|
||||||
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
label.TraefikFrontendAuthDigestUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
|
label.TraefikFrontendAuthDigestUsersFile: aws.String(".htpasswd"),
|
||||||
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
|
label.TraefikFrontendAuthForwardAddress: aws.String("auth.server"),
|
||||||
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
|
label.TraefikFrontendAuthForwardTrustForwardHeader: aws.String("true"),
|
||||||
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
|
label.TraefikFrontendAuthForwardTLSCa: aws.String("ca.crt"),
|
||||||
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
|
label.TraefikFrontendAuthForwardTLSCaOptional: aws.String("true"),
|
||||||
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
|
label.TraefikFrontendAuthForwardTLSCert: aws.String("server.crt"),
|
||||||
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
|
label.TraefikFrontendAuthForwardTLSKey: aws.String("server.key"),
|
||||||
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"),
|
label.TraefikFrontendAuthForwardTLSInsecureSkipVerify: aws.String("true"),
|
||||||
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
label.TraefikFrontendAuthHeaderField: aws.String("X-WebAuth-User"),
|
||||||
|
|
||||||
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
||||||
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
||||||
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
||||||
label.TraefikFrontendPriority: aws.String("666"),
|
label.TraefikFrontendPriority: aws.String("666"),
|
||||||
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
||||||
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
||||||
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
||||||
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
||||||
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
||||||
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
||||||
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
||||||
|
|
||||||
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
|
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.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.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.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
|
||||||
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
|
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
|
||||||
label.TraefikFrontendSSLHost: aws.String("foo"),
|
label.TraefikFrontendSSLHost: aws.String("foo"),
|
||||||
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
|
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
|
||||||
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
|
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
|
||||||
label.TraefikFrontendPublicKey: aws.String("foo"),
|
label.TraefikFrontendPublicKey: aws.String("foo"),
|
||||||
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
|
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
|
||||||
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
|
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
|
||||||
label.TraefikFrontendSTSSeconds: aws.String("666"),
|
label.TraefikFrontendSTSSeconds: aws.String("666"),
|
||||||
label.TraefikFrontendSSLForceHost: aws.String("true"),
|
label.TraefikFrontendSSLForceHost: aws.String("true"),
|
||||||
label.TraefikFrontendSSLRedirect: aws.String("true"),
|
label.TraefikFrontendSSLRedirect: aws.String("true"),
|
||||||
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
|
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
|
||||||
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
|
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
|
||||||
label.TraefikFrontendSTSPreload: aws.String("true"),
|
label.TraefikFrontendSTSPreload: aws.String("true"),
|
||||||
label.TraefikFrontendForceSTSHeader: aws.String("true"),
|
label.TraefikFrontendForceSTSHeader: aws.String("true"),
|
||||||
label.TraefikFrontendFrameDeny: aws.String("true"),
|
label.TraefikFrontendFrameDeny: aws.String("true"),
|
||||||
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
|
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
|
||||||
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
|
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
|
||||||
label.TraefikFrontendIsDevelopment: aws.String("true"),
|
label.TraefikFrontendIsDevelopment: aws.String("true"),
|
||||||
|
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
|
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.SuffixErrorPageBackend: aws.String("foobar"),
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
|
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.SuffixErrorPageStatus: aws.String("500,600"),
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
|
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 + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
|
||||||
|
|
||||||
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
|
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
|
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.SuffixRateLimitAverage: aws.String("12"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
|
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.SuffixRateLimitPeriod: aws.String("3"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
|
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
|
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
|
||||||
}},
|
}),
|
||||||
machine: &machine{
|
iMachine(
|
||||||
state: ec2.InstanceStateNameRunning,
|
mState(ec2.InstanceStateNameRunning),
|
||||||
privateIP: "10.0.0.1",
|
mPrivateIP("10.0.0.1"),
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPorts(
|
||||||
},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
@ -583,180 +589,182 @@ func TestBuildConfiguration(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "Containers with same backend name",
|
desc: "Containers with same backend name",
|
||||||
instances: []ecsInstance{
|
instances: []ecsInstance{
|
||||||
{
|
instance(
|
||||||
Name: "testing-instance-v1",
|
name("testing-instance-v1"),
|
||||||
ID: "6",
|
ID("6"),
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
dockerLabels(map[string]*string{
|
||||||
DockerLabels: map[string]*string{
|
label.TraefikPort: aws.String("666"),
|
||||||
label.TraefikPort: aws.String("666"),
|
label.TraefikProtocol: aws.String("https"),
|
||||||
label.TraefikProtocol: aws.String("https"),
|
label.TraefikWeight: aws.String("12"),
|
||||||
label.TraefikWeight: aws.String("12"),
|
|
||||||
|
|
||||||
label.TraefikBackend: aws.String("foobar"),
|
label.TraefikBackend: aws.String("foobar"),
|
||||||
|
|
||||||
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
|
label.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
|
||||||
label.TraefikBackendHealthCheckScheme: aws.String("http"),
|
label.TraefikBackendHealthCheckScheme: aws.String("http"),
|
||||||
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
||||||
label.TraefikBackendHealthCheckPort: aws.String("880"),
|
label.TraefikBackendHealthCheckPort: aws.String("880"),
|
||||||
label.TraefikBackendHealthCheckInterval: aws.String("6"),
|
label.TraefikBackendHealthCheckInterval: aws.String("6"),
|
||||||
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
|
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
|
||||||
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
||||||
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
||||||
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
||||||
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
||||||
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
||||||
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
||||||
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
|
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
|
||||||
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
|
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
|
||||||
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
|
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
|
||||||
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
|
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
|
||||||
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
|
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
|
||||||
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
|
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
|
||||||
|
|
||||||
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
label.TraefikFrontendAuthBasicUsers: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
||||||
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
||||||
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
||||||
label.TraefikFrontendPriority: aws.String("666"),
|
label.TraefikFrontendPriority: aws.String("666"),
|
||||||
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
||||||
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
||||||
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
||||||
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
||||||
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
||||||
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
||||||
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
||||||
|
|
||||||
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
|
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.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.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.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
|
||||||
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
|
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
|
||||||
label.TraefikFrontendSSLHost: aws.String("foo"),
|
label.TraefikFrontendSSLHost: aws.String("foo"),
|
||||||
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
|
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
|
||||||
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
|
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
|
||||||
label.TraefikFrontendPublicKey: aws.String("foo"),
|
label.TraefikFrontendPublicKey: aws.String("foo"),
|
||||||
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
|
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
|
||||||
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
|
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
|
||||||
label.TraefikFrontendSTSSeconds: aws.String("666"),
|
label.TraefikFrontendSTSSeconds: aws.String("666"),
|
||||||
label.TraefikFrontendSSLForceHost: aws.String("true"),
|
label.TraefikFrontendSSLForceHost: aws.String("true"),
|
||||||
label.TraefikFrontendSSLRedirect: aws.String("true"),
|
label.TraefikFrontendSSLRedirect: aws.String("true"),
|
||||||
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
|
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
|
||||||
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
|
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
|
||||||
label.TraefikFrontendSTSPreload: aws.String("true"),
|
label.TraefikFrontendSTSPreload: aws.String("true"),
|
||||||
label.TraefikFrontendForceSTSHeader: aws.String("true"),
|
label.TraefikFrontendForceSTSHeader: aws.String("true"),
|
||||||
label.TraefikFrontendFrameDeny: aws.String("true"),
|
label.TraefikFrontendFrameDeny: aws.String("true"),
|
||||||
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
|
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
|
||||||
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
|
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
|
||||||
label.TraefikFrontendIsDevelopment: aws.String("true"),
|
label.TraefikFrontendIsDevelopment: aws.String("true"),
|
||||||
|
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
|
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.SuffixErrorPageBackend: aws.String("foobar"),
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
|
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.SuffixErrorPageStatus: aws.String("500,600"),
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
|
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 + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
|
||||||
|
|
||||||
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
|
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
|
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.SuffixRateLimitAverage: aws.String("12"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
|
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.SuffixRateLimitPeriod: aws.String("3"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
|
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
|
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
|
||||||
}},
|
}),
|
||||||
machine: &machine{
|
iMachine(
|
||||||
state: ec2.InstanceStateNameRunning,
|
mState(ec2.InstanceStateNameRunning),
|
||||||
privateIP: "10.0.0.1",
|
mPrivateIP("10.0.0.1"),
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPorts(
|
||||||
},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
{
|
),
|
||||||
Name: "testing-instance-v2",
|
),
|
||||||
ID: "6",
|
instance(
|
||||||
containerDefinition: &ecs.ContainerDefinition{
|
name("testing-instance-v2"),
|
||||||
DockerLabels: map[string]*string{
|
ID("6"),
|
||||||
label.TraefikPort: aws.String("555"),
|
dockerLabels(map[string]*string{
|
||||||
label.TraefikProtocol: aws.String("https"),
|
label.TraefikPort: aws.String("555"),
|
||||||
label.TraefikWeight: aws.String("15"),
|
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.TraefikBackendCircuitBreakerExpression: aws.String("NetworkErrorRatio() > 0.5"),
|
||||||
label.TraefikBackendHealthCheckScheme: aws.String("http"),
|
label.TraefikBackendHealthCheckScheme: aws.String("http"),
|
||||||
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
label.TraefikBackendHealthCheckPath: aws.String("/health"),
|
||||||
label.TraefikBackendHealthCheckPort: aws.String("880"),
|
label.TraefikBackendHealthCheckPort: aws.String("880"),
|
||||||
label.TraefikBackendHealthCheckInterval: aws.String("6"),
|
label.TraefikBackendHealthCheckInterval: aws.String("6"),
|
||||||
label.TraefikBackendHealthCheckHostname: aws.String("bar.com"),
|
label.TraefikBackendHealthCheckHostname: aws.String("bar.com"),
|
||||||
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
||||||
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
||||||
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
||||||
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
||||||
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
||||||
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
||||||
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
|
label.TraefikBackendMaxConnExtractorFunc: aws.String("client.ip"),
|
||||||
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
|
label.TraefikBackendBufferingMaxResponseBodyBytes: aws.String("10485760"),
|
||||||
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
|
label.TraefikBackendBufferingMemResponseBodyBytes: aws.String("2097152"),
|
||||||
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
|
label.TraefikBackendBufferingMaxRequestBodyBytes: aws.String("10485760"),
|
||||||
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
|
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
|
||||||
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
|
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
|
||||||
|
|
||||||
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||||
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
||||||
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
||||||
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
||||||
label.TraefikFrontendPriority: aws.String("666"),
|
label.TraefikFrontendPriority: aws.String("666"),
|
||||||
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
||||||
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
||||||
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
||||||
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
||||||
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
||||||
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
||||||
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
||||||
|
|
||||||
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
|
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.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.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.TraefikFrontendAllowedHosts: aws.String("foo,bar,bor"),
|
||||||
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
|
label.TraefikFrontendHostsProxyHeaders: aws.String("foo,bar,bor"),
|
||||||
label.TraefikFrontendSSLHost: aws.String("foo"),
|
label.TraefikFrontendSSLHost: aws.String("foo"),
|
||||||
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
|
label.TraefikFrontendCustomFrameOptionsValue: aws.String("foo"),
|
||||||
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
|
label.TraefikFrontendContentSecurityPolicy: aws.String("foo"),
|
||||||
label.TraefikFrontendPublicKey: aws.String("foo"),
|
label.TraefikFrontendPublicKey: aws.String("foo"),
|
||||||
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
|
label.TraefikFrontendReferrerPolicy: aws.String("foo"),
|
||||||
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
|
label.TraefikFrontendCustomBrowserXSSValue: aws.String("foo"),
|
||||||
label.TraefikFrontendSTSSeconds: aws.String("666"),
|
label.TraefikFrontendSTSSeconds: aws.String("666"),
|
||||||
label.TraefikFrontendSSLForceHost: aws.String("true"),
|
label.TraefikFrontendSSLForceHost: aws.String("true"),
|
||||||
label.TraefikFrontendSSLRedirect: aws.String("true"),
|
label.TraefikFrontendSSLRedirect: aws.String("true"),
|
||||||
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
|
label.TraefikFrontendSSLTemporaryRedirect: aws.String("true"),
|
||||||
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
|
label.TraefikFrontendSTSIncludeSubdomains: aws.String("true"),
|
||||||
label.TraefikFrontendSTSPreload: aws.String("true"),
|
label.TraefikFrontendSTSPreload: aws.String("true"),
|
||||||
label.TraefikFrontendForceSTSHeader: aws.String("true"),
|
label.TraefikFrontendForceSTSHeader: aws.String("true"),
|
||||||
label.TraefikFrontendFrameDeny: aws.String("true"),
|
label.TraefikFrontendFrameDeny: aws.String("true"),
|
||||||
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
|
label.TraefikFrontendContentTypeNosniff: aws.String("true"),
|
||||||
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
|
label.TraefikFrontendBrowserXSSFilter: aws.String("true"),
|
||||||
label.TraefikFrontendIsDevelopment: aws.String("true"),
|
label.TraefikFrontendIsDevelopment: aws.String("true"),
|
||||||
|
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: aws.String("404"),
|
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.SuffixErrorPageBackend: aws.String("foobar"),
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: aws.String("foo_query"),
|
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.SuffixErrorPageStatus: aws.String("500,600"),
|
||||||
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: aws.String("foobar"),
|
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 + "bar." + label.SuffixErrorPageQuery: aws.String("bar_query"),
|
||||||
|
|
||||||
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
|
label.TraefikFrontendRateLimitExtractorFunc: aws.String("client.ip"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: aws.String("6"),
|
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.SuffixRateLimitAverage: aws.String("12"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: aws.String("18"),
|
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.SuffixRateLimitPeriod: aws.String("3"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
|
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: aws.String("6"),
|
||||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
|
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: aws.String("9"),
|
||||||
}},
|
}),
|
||||||
machine: &machine{
|
iMachine(
|
||||||
state: ec2.InstanceStateNameRunning,
|
mState(ec2.InstanceStateNameRunning),
|
||||||
privateIP: "10.2.2.1",
|
mPrivateIP("10.2.2.1"),
|
||||||
ports: []portMapping{{hostPort: 1337}},
|
mPorts(
|
||||||
},
|
mPort(0, 1337),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
expected: &types.Configuration{
|
expected: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{
|
Backends: map[string]*types.Backend{
|
||||||
|
|
|
@ -45,7 +45,7 @@ func (p *Provider) buildConfigurationV1(instances []ecsInstance) (*types.Configu
|
||||||
|
|
||||||
// Frontend functions
|
// Frontend functions
|
||||||
"filterFrontends": filterFrontendsV1,
|
"filterFrontends": filterFrontendsV1,
|
||||||
"getFrontendRule": p.getFrontendRule,
|
"getFrontendRule": p.getFrontendRuleV1,
|
||||||
"getPassHostHeader": getFuncBoolValueV1(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
|
"getPassHostHeader": getFuncBoolValueV1(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
|
||||||
"getPassTLSCert": getFuncBoolValueV1(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
"getPassTLSCert": getFuncBoolValueV1(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||||
"getPriority": getFuncIntValueV1(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
"getPriority": getFuncIntValueV1(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
||||||
|
@ -70,7 +70,7 @@ func filterFrontendsV1(instances []ecsInstance) []ecsInstance {
|
||||||
byName := make(map[string]struct{})
|
byName := make(map[string]struct{})
|
||||||
|
|
||||||
return fun.Filter(func(i ecsInstance) bool {
|
return fun.Filter(func(i ecsInstance) bool {
|
||||||
backendName := getBackendName(i)
|
backendName := getBackendNameV1(i)
|
||||||
_, found := byName[backendName]
|
_, found := byName[backendName]
|
||||||
if !found {
|
if !found {
|
||||||
byName[backendName] = struct{}{}
|
byName[backendName] = struct{}{}
|
||||||
|
@ -79,6 +79,14 @@ func filterFrontendsV1(instances []ecsInstance) []ecsInstance {
|
||||||
}, instances).([]ecsInstance)
|
}, instances).([]ecsInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
func (p *Provider) getFrontendRuleV1(i ecsInstance) string {
|
||||||
|
domain := label.GetStringValue(i.TraefikLabels, label.TraefikDomain, p.Domain)
|
||||||
|
defaultRule := "Host:" + strings.ToLower(strings.Replace(i.Name, "_", "-", -1)) + "." + domain
|
||||||
|
|
||||||
|
return label.GetStringValue(i.TraefikLabels, label.TraefikFrontendRule, defaultRule)
|
||||||
|
}
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
func (p *Provider) filterInstanceV1(i ecsInstance) bool {
|
func (p *Provider) filterInstanceV1(i ecsInstance) bool {
|
||||||
if i.machine == nil {
|
if i.machine == nil {
|
||||||
|
|
|
@ -46,6 +46,8 @@ type ecsInstance struct {
|
||||||
containerDefinition *ecs.ContainerDefinition
|
containerDefinition *ecs.ContainerDefinition
|
||||||
machine *machine
|
machine *machine
|
||||||
TraefikLabels map[string]string
|
TraefikLabels map[string]string
|
||||||
|
SegmentLabels map[string]string
|
||||||
|
SegmentName string
|
||||||
}
|
}
|
||||||
|
|
||||||
type portMapping struct {
|
type portMapping struct {
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
{{range $serviceName, $instances := .Services }}
|
{{range $serviceName, $instances := .Services }}
|
||||||
{{ $firstInstance := index $instances 0 }}
|
{{ $firstInstance := index $instances 0 }}
|
||||||
|
|
||||||
{{ $circuitBreaker := getCircuitBreaker $firstInstance.TraefikLabels }}
|
{{ $circuitBreaker := getCircuitBreaker $firstInstance.SegmentLabels }}
|
||||||
{{if $circuitBreaker }}
|
{{if $circuitBreaker }}
|
||||||
[backends."backend-{{ $serviceName }}".circuitBreaker]
|
[backends."backend-{{ $serviceName }}".circuitBreaker]
|
||||||
expression = "{{ $circuitBreaker.Expression }}"
|
expression = "{{ $circuitBreaker.Expression }}"
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $loadBalancer := getLoadBalancer $firstInstance.TraefikLabels }}
|
{{ $loadBalancer := getLoadBalancer $firstInstance.SegmentLabels }}
|
||||||
{{if $loadBalancer }}
|
{{if $loadBalancer }}
|
||||||
[backends."backend-{{ $serviceName }}".loadBalancer]
|
[backends."backend-{{ $serviceName }}".loadBalancer]
|
||||||
method = "{{ $loadBalancer.Method }}"
|
method = "{{ $loadBalancer.Method }}"
|
||||||
|
@ -19,14 +19,14 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $maxConn := getMaxConn $firstInstance.TraefikLabels }}
|
{{ $maxConn := getMaxConn $firstInstance.SegmentLabels }}
|
||||||
{{if $maxConn }}
|
{{if $maxConn }}
|
||||||
[backends."backend-{{ $serviceName }}".maxConn]
|
[backends."backend-{{ $serviceName }}".maxConn]
|
||||||
extractorFunc = "{{ $maxConn.ExtractorFunc }}"
|
extractorFunc = "{{ $maxConn.ExtractorFunc }}"
|
||||||
amount = {{ $maxConn.Amount }}
|
amount = {{ $maxConn.Amount }}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $healthCheck := getHealthCheck $firstInstance.TraefikLabels }}
|
{{ $healthCheck := getHealthCheck $firstInstance.SegmentLabels }}
|
||||||
{{if $healthCheck }}
|
{{if $healthCheck }}
|
||||||
[backends."backend-{{ $serviceName }}".healthCheck]
|
[backends."backend-{{ $serviceName }}".healthCheck]
|
||||||
scheme = "{{ $healthCheck.Scheme }}"
|
scheme = "{{ $healthCheck.Scheme }}"
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $buffering := getBuffering $firstInstance.TraefikLabels }}
|
{{ $buffering := getBuffering $firstInstance.SegmentLabels }}
|
||||||
{{if $buffering }}
|
{{if $buffering }}
|
||||||
[backends."backend-{{ $serviceName }}".buffering]
|
[backends."backend-{{ $serviceName }}".buffering]
|
||||||
maxRequestBodyBytes = {{ $buffering.MaxRequestBodyBytes }}
|
maxRequestBodyBytes = {{ $buffering.MaxRequestBodyBytes }}
|
||||||
|
@ -64,28 +64,30 @@
|
||||||
{{range $serviceName, $instances := .Services }}
|
{{range $serviceName, $instances := .Services }}
|
||||||
{{range $instance := filterFrontends $instances }}
|
{{range $instance := filterFrontends $instances }}
|
||||||
|
|
||||||
[frontends."frontend-{{ $serviceName }}"]
|
{{ $frontendName := getFrontendName $instance }}
|
||||||
backend = "backend-{{ $serviceName }}"
|
|
||||||
priority = {{ getPriority $instance.TraefikLabels }}
|
|
||||||
passHostHeader = {{ getPassHostHeader $instance.TraefikLabels }}
|
|
||||||
passTLSCert = {{ getPassTLSCert $instance.TraefikLabels }}
|
|
||||||
|
|
||||||
entryPoints = [{{range getEntryPoints $instance.TraefikLabels }}
|
[frontends."frontend-{{ $frontendName }}"]
|
||||||
|
backend = "backend-{{ $serviceName }}"
|
||||||
|
priority = {{ getPriority $instance.SegmentLabels }}
|
||||||
|
passHostHeader = {{ getPassHostHeader $instance.SegmentLabels }}
|
||||||
|
passTLSCert = {{ getPassTLSCert $instance.SegmentLabels }}
|
||||||
|
|
||||||
|
entryPoints = [{{range getEntryPoints $instance.SegmentLabels }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
|
|
||||||
{{ $auth := getAuth $instance.TraefikLabels }}
|
{{ $auth := getAuth $instance.SegmentLabels }}
|
||||||
{{if $auth }}
|
{{if $auth }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth]
|
[frontends."frontend-{{ $frontendName }}".auth]
|
||||||
headerField = "{{ $auth.HeaderField }}"
|
headerField = "{{ $auth.HeaderField }}"
|
||||||
|
|
||||||
{{if $auth.Forward }}
|
{{if $auth.Forward }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.forward]
|
[frontends."frontend-{{ $frontendName }}".auth.forward]
|
||||||
address = "{{ $auth.Forward.Address }}"
|
address = "{{ $auth.Forward.Address }}"
|
||||||
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
|
trustForwardHeader = {{ $auth.Forward.TrustForwardHeader }}
|
||||||
|
|
||||||
{{if $auth.Forward.TLS }}
|
{{if $auth.Forward.TLS }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.forward.tls]
|
[frontends."frontend-{{ $frontendName }}".auth.forward.tls]
|
||||||
ca = "{{ $auth.Forward.TLS.CA }}"
|
ca = "{{ $auth.Forward.TLS.CA }}"
|
||||||
caOptional = {{ $auth.Forward.TLS.CAOptional }}
|
caOptional = {{ $auth.Forward.TLS.CAOptional }}
|
||||||
cert = """{{ $auth.Forward.TLS.Cert }}"""
|
cert = """{{ $auth.Forward.TLS.Cert }}"""
|
||||||
|
@ -95,7 +97,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $auth.Basic }}
|
{{if $auth.Basic }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.basic]
|
[frontends."frontend-{{ $frontendName }}".auth.basic]
|
||||||
removeHeader = {{ $auth.Basic.RemoveHeader }}
|
removeHeader = {{ $auth.Basic.RemoveHeader }}
|
||||||
{{if $auth.Basic.Users }}
|
{{if $auth.Basic.Users }}
|
||||||
users = [{{range $auth.Basic.Users }}
|
users = [{{range $auth.Basic.Users }}
|
||||||
|
@ -106,7 +108,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $auth.Digest }}
|
{{if $auth.Digest }}
|
||||||
[frontends."frontend-{{ $serviceName }}".auth.digest]
|
[frontends."frontend-{{ $frontendName }}".auth.digest]
|
||||||
removeHeader = {{ $auth.Digest.RemoveHeader }}
|
removeHeader = {{ $auth.Digest.RemoveHeader }}
|
||||||
{{if $auth.Digest.Users }}
|
{{if $auth.Digest.Users }}
|
||||||
users = [{{range $auth.Digest.Users }}
|
users = [{{range $auth.Digest.Users }}
|
||||||
|
@ -117,29 +119,29 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $whitelist := getWhiteList $instance.TraefikLabels }}
|
{{ $whitelist := getWhiteList $instance.SegmentLabels }}
|
||||||
{{if $whitelist }}
|
{{if $whitelist }}
|
||||||
[frontends."frontend-{{ $serviceName }}".whiteList]
|
[frontends."frontend-{{ $frontendName }}".whiteList]
|
||||||
sourceRange = [{{range $whitelist.SourceRange }}
|
sourceRange = [{{range $whitelist.SourceRange }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
useXForwardedFor = {{ $whitelist.UseXForwardedFor }}
|
useXForwardedFor = {{ $whitelist.UseXForwardedFor }}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $redirect := getRedirect $instance.TraefikLabels }}
|
{{ $redirect := getRedirect $instance.SegmentLabels }}
|
||||||
{{if $redirect }}
|
{{if $redirect }}
|
||||||
[frontends."frontend-{{ $serviceName }}".redirect]
|
[frontends."frontend-{{ $frontendName }}".redirect]
|
||||||
entryPoint = "{{ $redirect.EntryPoint }}"
|
entryPoint = "{{ $redirect.EntryPoint }}"
|
||||||
regex = "{{ $redirect.Regex }}"
|
regex = "{{ $redirect.Regex }}"
|
||||||
replacement = "{{ $redirect.Replacement }}"
|
replacement = "{{ $redirect.Replacement }}"
|
||||||
permanent = {{ $redirect.Permanent }}
|
permanent = {{ $redirect.Permanent }}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $errorPages := getErrorPages $instance.TraefikLabels }}
|
{{ $errorPages := getErrorPages $instance.SegmentLabels }}
|
||||||
{{if $errorPages }}
|
{{if $errorPages }}
|
||||||
[frontends."frontend-{{ $serviceName }}".errors]
|
[frontends."frontend-{{ $frontendName }}".errors]
|
||||||
{{range $pageName, $page := $errorPages }}
|
{{range $pageName, $page := $errorPages }}
|
||||||
[frontends."frontend-{{ $serviceName }}".errors."{{ $pageName }}"]
|
[frontends."frontend-{{ $frontendName }}".errors."{{ $pageName }}"]
|
||||||
status = [{{range $page.Status }}
|
status = [{{range $page.Status }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
|
@ -148,22 +150,22 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $rateLimit := getRateLimit $instance.TraefikLabels }}
|
{{ $rateLimit := getRateLimit $instance.SegmentLabels }}
|
||||||
{{if $rateLimit }}
|
{{if $rateLimit }}
|
||||||
[frontends."frontend-{{ $serviceName }}".rateLimit]
|
[frontends."frontend-{{ $frontendName }}".rateLimit]
|
||||||
extractorFunc = "{{ $rateLimit.ExtractorFunc }}"
|
extractorFunc = "{{ $rateLimit.ExtractorFunc }}"
|
||||||
[frontends."frontend-{{ $serviceName }}".rateLimit.rateSet]
|
[frontends."frontend-{{ $frontendName }}".rateLimit.rateSet]
|
||||||
{{ range $limitName, $limit := $rateLimit.RateSet }}
|
{{ range $limitName, $limit := $rateLimit.RateSet }}
|
||||||
[frontends."frontend-{{ $serviceName }}".rateLimit.rateSet."{{ $limitName }}"]
|
[frontends."frontend-{{ $frontendName }}".rateLimit.rateSet."{{ $limitName }}"]
|
||||||
period = "{{ $limit.Period }}"
|
period = "{{ $limit.Period }}"
|
||||||
average = {{ $limit.Average }}
|
average = {{ $limit.Average }}
|
||||||
burst = {{ $limit.Burst }}
|
burst = {{ $limit.Burst }}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{ $headers := getHeaders $instance.TraefikLabels }}
|
{{ $headers := getHeaders $instance.SegmentLabels }}
|
||||||
{{if $headers }}
|
{{if $headers }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers]
|
[frontends."frontend-{{ $frontendName }}".headers]
|
||||||
SSLRedirect = {{ $headers.SSLRedirect }}
|
SSLRedirect = {{ $headers.SSLRedirect }}
|
||||||
SSLTemporaryRedirect = {{ $headers.SSLTemporaryRedirect }}
|
SSLTemporaryRedirect = {{ $headers.SSLTemporaryRedirect }}
|
||||||
SSLHost = "{{ $headers.SSLHost }}"
|
SSLHost = "{{ $headers.SSLHost }}"
|
||||||
|
@ -195,28 +197,28 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $headers.CustomRequestHeaders }}
|
{{if $headers.CustomRequestHeaders }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers.customRequestHeaders]
|
[frontends."frontend-{{ $frontendName }}".headers.customRequestHeaders]
|
||||||
{{range $k, $v := $headers.CustomRequestHeaders }}
|
{{range $k, $v := $headers.CustomRequestHeaders }}
|
||||||
{{$k}} = "{{$v}}"
|
{{$k}} = "{{$v}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $headers.CustomResponseHeaders }}
|
{{if $headers.CustomResponseHeaders }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers.customResponseHeaders]
|
[frontends."frontend-{{ $frontendName }}".headers.customResponseHeaders]
|
||||||
{{range $k, $v := $headers.CustomResponseHeaders }}
|
{{range $k, $v := $headers.CustomResponseHeaders }}
|
||||||
{{$k}} = "{{$v}}"
|
{{$k}} = "{{$v}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $headers.SSLProxyHeaders }}
|
{{if $headers.SSLProxyHeaders }}
|
||||||
[frontends."frontend-{{ $serviceName }}".headers.SSLProxyHeaders]
|
[frontends."frontend-{{ $frontendName }}".headers.SSLProxyHeaders]
|
||||||
{{range $k, $v := $headers.SSLProxyHeaders }}
|
{{range $k, $v := $headers.SSLProxyHeaders }}
|
||||||
{{$k}} = "{{$v}}"
|
{{$k}} = "{{$v}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
[frontends."frontend-{{ $serviceName }}".routes."route-frontend-{{ $serviceName }}"]
|
[frontends."frontend-{{ $frontendName }}".routes."route-frontend-{{ $frontendName }}"]
|
||||||
rule = "{{ getFrontendRule $instance }}"
|
rule = "{{ getFrontendRule $instance }}"
|
||||||
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
Loading…
Reference in a new issue