From f611ef0eddd7a92232cb8d0d4a4f6bd5bdea1b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rald=20Cro=C3=ABs?= Date: Mon, 23 Jul 2018 11:56:02 +0200 Subject: [PATCH] Removes templates --- autogen/gentemplates/gen.go | 604 +---------- provider/consulcatalog/config.go | 7 +- provider/consulcatalog/config_root.go | 10 - provider/consulcatalog/config_test.go | 2 +- provider/consulcatalog/deprecated_config.go | 228 ----- .../consulcatalog/deprecated_config_test.go | 444 -------- provider/docker/config.go | 2 +- .../docker/config_container_docker_test.go | 2 +- .../docker/config_container_swarm_test.go | 2 +- provider/docker/config_root.go | 12 - provider/docker/config_segment_test.go | 2 +- provider/docker/deprecated_config.go | 263 ----- provider/docker/deprecated_container.go | 216 ---- .../deprecated_container_docker_test.go | 969 ------------------ .../docker/deprecated_container_swarm_test.go | 709 ------------- provider/docker/deprecated_service.go | 197 ---- provider/docker/deprecated_service_test.go | 695 ------------- provider/ecs/config.go | 2 +- provider/ecs/config_root.go | 12 - provider/ecs/config_test.go | 76 -- provider/ecs/deprecated_config.go | 260 ----- provider/ecs/deprecated_config_test.go | 395 ------- provider/marathon/config.go | 2 +- provider/marathon/config_root.go | 13 - provider/marathon/config_test.go | 4 +- provider/marathon/deprecated_config.go | 436 -------- provider/marathon/deprecated_config_test.go | 895 ---------------- provider/mesos/config.go | 2 +- provider/mesos/config_root.go | 13 - provider/mesos/config_test.go | 4 +- provider/mesos/deprecated_config.go | 329 ------ provider/mesos/deprecated_config_test.go | 432 -------- provider/rancher/config.go | 2 +- provider/rancher/config_root.go | 12 - provider/rancher/deprecated_config.go | 233 ----- provider/rancher/deprecated_config_test.go | 503 --------- templates/consul_catalog-v1.tmpl | 56 - templates/docker-v1.tmpl | 192 ---- templates/ecs-v1.tmpl | 44 - templates/marathon-v1.tmpl | 68 -- templates/mesos-v1.tmpl | 27 - templates/rancher-v1.tmpl | 58 -- 42 files changed, 37 insertions(+), 8397 deletions(-) delete mode 100644 provider/consulcatalog/config_root.go delete mode 100644 provider/consulcatalog/deprecated_config.go delete mode 100644 provider/consulcatalog/deprecated_config_test.go delete mode 100644 provider/docker/config_root.go delete mode 100644 provider/docker/deprecated_config.go delete mode 100644 provider/docker/deprecated_container.go delete mode 100644 provider/docker/deprecated_container_docker_test.go delete mode 100644 provider/docker/deprecated_container_swarm_test.go delete mode 100644 provider/docker/deprecated_service.go delete mode 100644 provider/docker/deprecated_service_test.go delete mode 100644 provider/ecs/config_root.go delete mode 100644 provider/ecs/deprecated_config.go delete mode 100644 provider/ecs/deprecated_config_test.go delete mode 100644 provider/marathon/config_root.go delete mode 100644 provider/marathon/deprecated_config.go delete mode 100644 provider/marathon/deprecated_config_test.go delete mode 100644 provider/mesos/config_root.go delete mode 100644 provider/mesos/deprecated_config.go delete mode 100644 provider/mesos/deprecated_config_test.go delete mode 100644 provider/rancher/config_root.go delete mode 100644 provider/rancher/deprecated_config.go delete mode 100644 provider/rancher/deprecated_config_test.go delete mode 100644 templates/consul_catalog-v1.tmpl delete mode 100644 templates/docker-v1.tmpl delete mode 100644 templates/ecs-v1.tmpl delete mode 100644 templates/marathon-v1.tmpl delete mode 100644 templates/mesos-v1.tmpl delete mode 100644 templates/rancher-v1.tmpl diff --git a/autogen/gentemplates/gen.go b/autogen/gentemplates/gen.go index 5390fbe2d..ff1f523fd 100644 --- a/autogen/gentemplates/gen.go +++ b/autogen/gentemplates/gen.go @@ -1,20 +1,14 @@ // Code generated by go-bindata. // sources: -// templates/consul_catalog-v1.tmpl // templates/consul_catalog.tmpl -// templates/docker-v1.tmpl // templates/docker.tmpl -// templates/ecs-v1.tmpl // templates/ecs.tmpl // templates/eureka.tmpl // templates/kubernetes.tmpl // templates/kv.tmpl -// templates/marathon-v1.tmpl // templates/marathon.tmpl -// templates/mesos-v1.tmpl // templates/mesos.tmpl // templates/notFound.tmpl -// templates/rancher-v1.tmpl // templates/rancher.tmpl // DO NOT EDIT! @@ -60,79 +54,6 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templatesConsul_catalogV1Tmpl = []byte(`[backends] -{{range $index, $node := .Nodes }} - [backends."backend-{{ getBackend $node }}".servers."{{ getBackendName $node $index }}"] - url = "{{ getAttribute "protocol" $node.Service.Tags "http" }}://{{ getBackendAddress $node }}:{{ $node.Service.Port }}" - {{ $weight := getAttribute "backend.weight" $node.Service.Tags "0" }} - {{with $weight }} - weight = {{ $weight }} - {{end}} -{{end}} - -{{range .Services }} - {{ $service := .ServiceName }} - - {{ $circuitBreaker := getAttribute "backend.circuitbreaker" .Attributes "" }} - {{with $circuitBreaker }} - [backends."backend-{{ $service }}".circuitbreaker] - expression = "{{ $circuitBreaker }}" - {{end}} - - [backends."backend-{{ $service }}".loadbalancer] - method = "{{ getAttribute "backend.loadbalancer" .Attributes "wrr" }}" - sticky = {{ getSticky .Attributes }} - {{if hasStickinessLabel .Attributes }} - [backends."backend-{{ $service }}".loadbalancer.stickiness] - cookieName = "{{ getStickinessCookieName .Attributes }}" - {{end}} - - {{if hasMaxconnAttributes .Attributes }} - [backends."backend-{{ $service }}".maxconn] - amount = {{ getAttribute "backend.maxconn.amount" .Attributes "" }} - extractorfunc = "{{ getAttribute "backend.maxconn.extractorfunc" .Attributes "" }}" - {{end}} - -{{end}} - -[frontends] -{{range .Services }} - [frontends."frontend-{{ .ServiceName }}"] - backend = "backend-{{ .ServiceName }}" - passHostHeader = {{ getAttribute "frontend.passHostHeader" .Attributes "true" }} - priority = {{ getAttribute "frontend.priority" .Attributes "0" }} - - {{ $entryPoints := getAttribute "frontend.entrypoints" .Attributes "" }} - {{with $entryPoints }} - entrypoints = [{{range getEntryPoints $entryPoints }} - "{{ . }}", - {{end}}] - {{end}} - - basicAuth = [{{range getBasicAuth .Attributes }} - "{{ . }}", - {{end}}] - - [frontends."frontend-{{ .ServiceName }}".routes."route-host-{{ .ServiceName }}"] - rule = "{{ getFrontendRule . }}" -{{end}} -`) - -func templatesConsul_catalogV1TmplBytes() ([]byte, error) { - return _templatesConsul_catalogV1Tmpl, nil -} - -func templatesConsul_catalogV1Tmpl() (*asset, error) { - bytes, err := templatesConsul_catalogV1TmplBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/consul_catalog-v1.tmpl", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _templatesConsul_catalogTmpl = []byte(`[backends] {{range $service := .Services}} {{ $backendName := getServiceBackendName $service }} @@ -373,215 +294,6 @@ func templatesConsul_catalogTmpl() (*asset, error) { return a, nil } -var _templatesDockerV1Tmpl = []byte(`{{$backendServers := .Servers}} - -[backends] -{{range $backendName, $backend := .Backends }} - - {{if hasCircuitBreakerLabel $backend }} - [backends."backend-{{ $backendName }}".circuitbreaker] - expression = "{{ getCircuitBreakerExpression $backend }}" - {{end}} - - {{if hasLoadBalancerLabel $backend }} - [backends."backend-{{ $backendName }}".loadbalancer] - method = "{{ getLoadBalancerMethod $backend }}" - sticky = {{ getSticky $backend }} - {{if hasStickinessLabel $backend }} - [backends."backend-{{ $backendName }}".loadbalancer.stickiness] - cookieName = "{{ getStickinessCookieName $backend }}" - {{end}} - {{end}} - - {{if hasMaxConnLabels $backend }} - [backends."backend-{{ $backendName }}".maxconn] - amount = {{ getMaxConnAmount $backend }} - extractorfunc = "{{ getMaxConnExtractorFunc $backend }}" - {{end}} - - {{ $servers := index $backendServers $backendName }} - {{range $serverName, $server := $servers }} - {{if hasServices $server }} - {{$services := getServiceNames $server }} - {{range $serviceIndex, $serviceName := $services }} - [backends."backend-{{ getServiceBackend $server $serviceName }}".servers."service-{{ $serverName }}"] - url = "{{ getServiceProtocol $server $serviceName }}://{{ getIPAddress $server }}:{{ getServicePort $server $serviceName }}" - weight = {{ getServiceWeight $server $serviceName }} - {{end}} - {{else}} - [backends."backend-{{ $backendName }}".servers."server-{{$server.Name | replace "/" "" | replace "." "-"}}"] - url = "{{ getProtocol $server }}://{{ getIPAddress $server }}:{{ getPort $server }}" - weight = {{ getWeight $server }} - {{end}} - {{end}} - -{{end}} - -[frontends] -{{range $frontend, $containers := .Frontends}} - {{$container := index $containers 0}} - - {{if hasServices $container }} - {{ $services := getServiceNames $container }} - {{range $serviceIndex, $serviceName := $services }} - [frontends."frontend-{{ getServiceBackend $container $serviceName }}"] - backend = "backend-{{ getServiceBackend $container $serviceName }}" - passHostHeader = {{ getServicePassHostHeader $container $serviceName }} - passTLSCert = {{ getServicePassTLSCert $container $serviceName }} - - {{if getWhitelistSourceRange $container }} - whitelistSourceRange = [{{range getWhitelistSourceRange $container }} - "{{.}}", - {{end}}] - {{end}} - - priority = {{ getServicePriority $container $serviceName }} - - entryPoints = [{{range getServiceEntryPoints $container $serviceName }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getServiceBasicAuth $container $serviceName }} - "{{.}}", - {{end}}] - - {{if hasServiceRedirect $container $serviceName }} - [frontends."frontend-{{ getServiceBackend $container $serviceName }}".redirect] - entryPoint = "{{ getServiceRedirectEntryPoint $container $serviceName }}" - regex = "{{ getServiceRedirectRegex $container $serviceName }}" - replacement = "{{ getServiceRedirectReplacement $container $serviceName }}" - {{end}} - - [frontends."frontend-{{ getServiceBackend $container $serviceName }}".routes."service-{{ $serviceName | replace "/" "" | replace "." "-" }}"] - rule = "{{ getServiceFrontendRule $container $serviceName }}" - {{end}} - {{else}} - [frontends."frontend-{{ $frontend }}"] - backend = "backend-{{ getBackend $container }}" - passHostHeader = {{ getPassHostHeader $container}} - passTLSCert = {{ getPassTLSCert $container }} - priority = {{ getPriority $container }} - - {{if getWhitelistSourceRange $container}} - whitelistSourceRange = [{{range getWhitelistSourceRange $container}} - "{{.}}", - {{end}}] - {{end}} - - entryPoints = [{{range getEntryPoints $container }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth $container }} - "{{.}}", - {{end}}] - - {{if hasRedirect $container}} - [frontends."frontend-{{$frontend}}".redirect] - entryPoint = "{{getRedirectEntryPoint $container}}" - regex = "{{getRedirectRegex $container}}" - replacement = "{{getRedirectReplacement $container}}" - {{end}} - - {{if hasHeaders $container }} - [frontends."frontend-{{ $frontend }}".headers] - {{if hasSSLRedirectHeaders $container}} - SSLRedirect = {{getSSLRedirectHeaders $container}} - {{end}} - {{if hasSSLTemporaryRedirectHeaders $container}} - SSLTemporaryRedirect = {{getSSLTemporaryRedirectHeaders $container}} - {{end}} - {{if hasSSLHostHeaders $container}} - SSLHost = "{{getSSLHostHeaders $container}}" - {{end}} - {{if hasSTSSecondsHeaders $container}} - STSSeconds = {{getSTSSecondsHeaders $container}} - {{end}} - {{if hasSTSIncludeSubdomainsHeaders $container}} - STSIncludeSubdomains = {{getSTSIncludeSubdomainsHeaders $container}} - {{end}} - {{if hasSTSPreloadHeaders $container}} - STSPreload = {{getSTSPreloadHeaders $container}} - {{end}} - {{if hasForceSTSHeaderHeaders $container}} - ForceSTSHeader = {{getForceSTSHeaderHeaders $container}} - {{end}} - {{if hasFrameDenyHeaders $container}} - FrameDeny = {{getFrameDenyHeaders $container}} - {{end}} - {{if hasCustomFrameOptionsValueHeaders $container}} - CustomFrameOptionsValue = "{{getCustomFrameOptionsValueHeaders $container}}" - {{end}} - {{if hasContentTypeNosniffHeaders $container}} - ContentTypeNosniff = {{getContentTypeNosniffHeaders $container}} - {{end}} - {{if hasBrowserXSSFilterHeaders $container}} - BrowserXSSFilter = {{getBrowserXSSFilterHeaders $container}} - {{end}} - {{if hasContentSecurityPolicyHeaders $container}} - ContentSecurityPolicy = "{{getContentSecurityPolicyHeaders $container}}" - {{end}} - {{if hasPublicKeyHeaders $container}} - PublicKey = "{{getPublicKeyHeaders $container}}" - {{end}} - {{if hasReferrerPolicyHeaders $container}} - ReferrerPolicy = "{{getReferrerPolicyHeaders $container}}" - {{end}} - {{if hasIsDevelopmentHeaders $container}} - IsDevelopment = {{getIsDevelopmentHeaders $container}} - {{end}} - {{if hasAllowedHostsHeaders $container}} - AllowedHosts = [{{range getAllowedHostsHeaders $container}} - "{{.}}", - {{end}}] - {{end}} - {{if hasHostsProxyHeaders $container}} - HostsProxyHeaders = [{{range getHostsProxyHeaders $container}} - "{{.}}", - {{end}}] - {{end}} - {{if hasRequestHeaders $container}} - [frontends."frontend-{{$frontend}}".headers.customrequestheaders] - {{range $k, $v := getRequestHeaders $container}} - {{$k}} = "{{$v}}" - {{end}} - {{end}} - {{if hasResponseHeaders $container}} - [frontends."frontend-{{$frontend}}".headers.customresponseheaders] - {{range $k, $v := getResponseHeaders $container}} - {{$k}} = "{{$v}}" - {{end}} - {{end}} - {{if hasSSLProxyHeaders $container}} - [frontends."frontend-{{$frontend}}".headers.SSLProxyHeaders] - {{range $k, $v := getSSLProxyHeaders $container}} - {{$k}} = "{{$v}}" - {{end}} - {{end}} - {{end}} - - [frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"] - rule = "{{getFrontendRule $container}}" - {{end}} - -{{end}} -`) - -func templatesDockerV1TmplBytes() ([]byte, error) { - return _templatesDockerV1Tmpl, nil -} - -func templatesDockerV1Tmpl() (*asset, error) { - bytes, err := templatesDockerV1TmplBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/docker-v1.tmpl", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}} [backends] {{range $backendName, $servers := .Servers}} @@ -823,66 +535,6 @@ func templatesDockerTmpl() (*asset, error) { return a, nil } -var _templatesEcsV1Tmpl = []byte(`[backends] -{{range $serviceName, $instances := .Services }} - [backends."backend-{{ $serviceName }}".loadBalancer] - method = "{{ getLoadBalancerMethod $instances }}" - sticky = {{ getLoadBalancerSticky $instances }} - - {{if hasStickinessLabel $instances }} - [backends."backend-{{ $serviceName }}".loadBalancer.stickiness] - cookieName = "{{ getStickinessCookieName $instances }}" - {{end}} - - {{ if hasHealthCheckLabels $instances }} - [backends."backend-{{ $serviceName }}".healthCheck] - path = "{{ getHealthCheckPath $instances }}" - interval = "{{ getHealthCheckInterval $instances }}" - {{end}} - - {{range $index, $i := $instances }} - [backends."backend-{{ $serviceName }}".servers."server-{{ $i.Name }}{{ $i.ID }}"] - url = "{{ getProtocol $i }}://{{ getHost $i }}:{{ getPort $i }}" - weight = {{ getWeight $i }} - {{end}} -{{end}} - -[frontends] -{{range $serviceName, $instances := .Services}} -{{range filterFrontends $instances }} - [frontends."frontend-{{ $serviceName }}"] - backend = "backend-{{ $serviceName }}" - passHostHeader = {{ getPassHostHeader . }} - priority = {{ getPriority . }} - - entryPoints = [{{range getEntryPoints . }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth . }} - "{{.}}", - {{end}}] - - [frontends."frontend-{{ $serviceName }}".routes."route-frontend-{{ $serviceName }}"] - rule = "{{getFrontendRule .}}" -{{end}} -{{end}}`) - -func templatesEcsV1TmplBytes() ([]byte, error) { - return _templatesEcsV1Tmpl, nil -} - -func templatesEcsV1Tmpl() (*asset, error) { - bytes, err := templatesEcsV1TmplBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/ecs-v1.tmpl", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _templatesEcsTmpl = []byte(`[backends] {{range $serviceName, $instances := .Services }} {{ $firstInstance := index $instances 0 }} @@ -1630,91 +1282,6 @@ func templatesKvTmpl() (*asset, error) { return a, nil } -var _templatesMarathonV1Tmpl = []byte(`{{$apps := .Applications}} - -{{range $app := $apps }} -{{range $task := $app.Tasks }} -{{range $serviceIndex, $serviceName := getServiceNames $app }} - [backends."{{ getBackend $app $serviceName }}".servers."server-{{ $task.ID | replace "." "-"}}{{getServiceNameSuffix $serviceName }}"] - url = "{{ getProtocol $app $serviceName }}://{{ getBackendServer $task $app }}:{{ getPort $task $app $serviceName }}" - weight = {{ getWeight $app $serviceName }} -{{end}} -{{end}} -{{end}} - -{{range $app := $apps }} -{{range $serviceIndex, $serviceName := getServiceNames $app }} - -[backends."{{ getBackend $app $serviceName }}"] - {{if hasMaxConnLabels $app }} - [backends."{{ getBackend $app $serviceName }}".maxConn] - amount = {{ getMaxConnAmount $app }} - extractorFunc = "{{ getMaxConnExtractorFunc $app }}" - {{end}} - - {{if hasLoadBalancerLabels $app }} - [backends."{{ getBackend $app $serviceName }}".loadBalancer] - method = "{{ getLoadBalancerMethod $app }}" - sticky = {{ getSticky $app }} - {{if hasStickinessLabel $app }} - [backends."{{ getBackend $app $serviceName }}".loadBalancer.stickiness] - cookieName = "{{ getStickinessCookieName $app }}" - {{end}} - {{end}} - - {{if hasCircuitBreakerLabels $app }} - [backends."{{ getBackend $app $serviceName }}".circuitBreaker] - expression = "{{ getCircuitBreakerExpression $app }}" - {{end}} - - {{if hasHealthCheckLabels $app }} - [backends."{{ getBackend $app $serviceName }}".healthCheck] - path = "{{ getHealthCheckPath $app }}" - interval = "{{ getHealthCheckInterval $app }}" - {{end}} - -{{end}} -{{end}} - -[frontends] -{{range $app := $apps }} -{{range $serviceIndex, $serviceName := getServiceNames . }} - - [frontends."{{ getFrontendName $app $serviceName | normalize }}"] - backend = "{{ getBackend $app $serviceName }}" - passHostHeader = {{ getPassHostHeader $app $serviceName }} - priority = {{ getPriority $app $serviceName }} - - entryPoints = [{{range getEntryPoints $app $serviceName }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth $app $serviceName }} - "{{.}}", - {{end}}] - - [frontends."{{ getFrontendName $app $serviceName | normalize }}".routes."route-host{{ $app.ID | replace "/" "-" }}{{ getServiceNameSuffix $serviceName }}"] - rule = "{{ getFrontendRule $app $serviceName }}" - -{{end}} -{{end}} -`) - -func templatesMarathonV1TmplBytes() ([]byte, error) { - return _templatesMarathonV1Tmpl, nil -} - -func templatesMarathonV1Tmpl() (*asset, error) { - bytes, err := templatesMarathonV1TmplBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/marathon-v1.tmpl", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _templatesMarathonTmpl = []byte(`{{ $apps := .Applications }} [backends] @@ -1957,50 +1524,6 @@ func templatesMarathonTmpl() (*asset, error) { return a, nil } -var _templatesMesosV1Tmpl = []byte(`{{$apps := .Applications}} - -[backends] -{{range .Tasks}} - - [backends."backend-{{ getBackend . $apps }}".servers."server-{{ getID . }}"] - url = "{{ getProtocol . $apps }}://{{ getHost . }}:{{ getPort . $apps }}" - weight = {{ getWeight . $apps }} - -{{end}} - -[frontends] -{{range .Applications}} - - [frontends."frontend-{{getFrontEndName . }}"] - backend = "backend-{{ getFrontendBackend . }}" - passHostHeader = {{ getPassHostHeader . }} - priority = {{ getPriority . }} - - entryPoints = [{{range getEntryPoints . }} - "{{.}}", - {{end}}] - - [frontends."frontend-{{ getFrontEndName . }}".routes."route-host-{{ getFrontEndName . }}"] - rule = "{{ getFrontendRule . }}" - -{{end}} -`) - -func templatesMesosV1TmplBytes() ([]byte, error) { - return _templatesMesosV1Tmpl, nil -} - -func templatesMesosV1Tmpl() (*asset, error) { - bytes, err := templatesMesosV1TmplBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/mesos-v1.tmpl", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _templatesMesosTmpl = []byte(`[backends] {{range $applicationName, $tasks := .ApplicationsTasks }} {{ $app := index $tasks 0 }} @@ -2267,81 +1790,6 @@ func templatesNotfoundTmpl() (*asset, error) { return a, nil } -var _templatesRancherV1Tmpl = []byte(`{{$backendServers := .Backends}} - -[backends] -{{range $backendName, $backend := .Backends }} - {{if hasCircuitBreakerLabel $backend }} - [backends."backend-{{ $backendName }}".circuitBreaker] - expression = "{{ getCircuitBreakerExpression $backend }}" - {{end}} - - {{if hasLoadBalancerLabel $backend }} - [backends."backend-{{ $backendName }}".loadBalancer] - method = "{{ getLoadBalancerMethod $backend }}" - sticky = {{ getSticky $backend }} - {{if hasStickinessLabel $backend }} - [backends."backend-{{ $backendName }}".loadBalancer.stickiness] - cookieName = "{{ getStickinessCookieName $backend }}" - {{end}} - {{end}} - - {{if hasMaxConnLabels $backend }} - [backends."backend-{{ $backendName }}".maxConn] - amount = {{ getMaxConnAmount $backend }} - extractorFunc = "{{ getMaxConnExtractorFunc $backend }}" - {{end}} - - {{range $index, $ip := $backend.Containers }} - [backends."backend-{{ $backendName }}".servers."server-{{ $index }}"] - url = "{{ getProtocol $backend }}://{{ $ip }}:{{ getPort $backend }}" - weight = {{ getWeight $backend }} - {{end}} - -{{end}} - -[frontends] -{{range $frontendName, $service := .Frontends }} - [frontends."frontend-{{ $frontendName }}"] - backend = "backend-{{ getBackend $service }}" - passHostHeader = {{ getPassHostHeader $service }} - priority = {{ getPriority $service }} - - entryPoints = [{{range getEntryPoints $service }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth $service }} - "{{.}}", - {{end}}] - - {{if hasRedirect $service }} - [frontends."frontend-{{ $frontendName }}".redirect] - entryPoint = "{{ getRedirectEntryPoint $service }}" - regex = "{{ getRedirectRegex $service }}" - replacement = "{{ getRedirectReplacement $service }}" - {{end}} - - [frontends."frontend-{{ $frontendName }}".routes."route-frontend-{{ $frontendName }}"] - rule = "{{ getFrontendRule $service }}" -{{end}} -`) - -func templatesRancherV1TmplBytes() ([]byte, error) { - return _templatesRancherV1Tmpl, nil -} - -func templatesRancherV1Tmpl() (*asset, error) { - bytes, err := templatesRancherV1TmplBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "templates/rancher-v1.tmpl", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - var _templatesRancherTmpl = []byte(`{{ $backendServers := .Backends }} [backends] {{range $backendName, $backend := .Backends }} @@ -2634,22 +2082,16 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "templates/consul_catalog-v1.tmpl": templatesConsul_catalogV1Tmpl, - "templates/consul_catalog.tmpl": templatesConsul_catalogTmpl, - "templates/docker-v1.tmpl": templatesDockerV1Tmpl, - "templates/docker.tmpl": templatesDockerTmpl, - "templates/ecs-v1.tmpl": templatesEcsV1Tmpl, - "templates/ecs.tmpl": templatesEcsTmpl, - "templates/eureka.tmpl": templatesEurekaTmpl, - "templates/kubernetes.tmpl": templatesKubernetesTmpl, - "templates/kv.tmpl": templatesKvTmpl, - "templates/marathon-v1.tmpl": templatesMarathonV1Tmpl, - "templates/marathon.tmpl": templatesMarathonTmpl, - "templates/mesos-v1.tmpl": templatesMesosV1Tmpl, - "templates/mesos.tmpl": templatesMesosTmpl, - "templates/notFound.tmpl": templatesNotfoundTmpl, - "templates/rancher-v1.tmpl": templatesRancherV1Tmpl, - "templates/rancher.tmpl": templatesRancherTmpl, + "templates/consul_catalog.tmpl": templatesConsul_catalogTmpl, + "templates/docker.tmpl": templatesDockerTmpl, + "templates/ecs.tmpl": templatesEcsTmpl, + "templates/eureka.tmpl": templatesEurekaTmpl, + "templates/kubernetes.tmpl": templatesKubernetesTmpl, + "templates/kv.tmpl": templatesKvTmpl, + "templates/marathon.tmpl": templatesMarathonTmpl, + "templates/mesos.tmpl": templatesMesosTmpl, + "templates/notFound.tmpl": templatesNotfoundTmpl, + "templates/rancher.tmpl": templatesRancherTmpl, } // AssetDir returns the file names below a certain @@ -2694,22 +2136,16 @@ type bintree struct { var _bintree = &bintree{nil, map[string]*bintree{ "templates": {nil, map[string]*bintree{ - "consul_catalog-v1.tmpl": {templatesConsul_catalogV1Tmpl, map[string]*bintree{}}, - "consul_catalog.tmpl": {templatesConsul_catalogTmpl, map[string]*bintree{}}, - "docker-v1.tmpl": {templatesDockerV1Tmpl, map[string]*bintree{}}, - "docker.tmpl": {templatesDockerTmpl, map[string]*bintree{}}, - "ecs-v1.tmpl": {templatesEcsV1Tmpl, map[string]*bintree{}}, - "ecs.tmpl": {templatesEcsTmpl, map[string]*bintree{}}, - "eureka.tmpl": {templatesEurekaTmpl, map[string]*bintree{}}, - "kubernetes.tmpl": {templatesKubernetesTmpl, map[string]*bintree{}}, - "kv.tmpl": {templatesKvTmpl, map[string]*bintree{}}, - "marathon-v1.tmpl": {templatesMarathonV1Tmpl, map[string]*bintree{}}, - "marathon.tmpl": {templatesMarathonTmpl, map[string]*bintree{}}, - "mesos-v1.tmpl": {templatesMesosV1Tmpl, map[string]*bintree{}}, - "mesos.tmpl": {templatesMesosTmpl, map[string]*bintree{}}, - "notFound.tmpl": {templatesNotfoundTmpl, map[string]*bintree{}}, - "rancher-v1.tmpl": {templatesRancherV1Tmpl, map[string]*bintree{}}, - "rancher.tmpl": {templatesRancherTmpl, map[string]*bintree{}}, + "consul_catalog.tmpl": {templatesConsul_catalogTmpl, map[string]*bintree{}}, + "docker.tmpl": {templatesDockerTmpl, map[string]*bintree{}}, + "ecs.tmpl": {templatesEcsTmpl, map[string]*bintree{}}, + "eureka.tmpl": {templatesEurekaTmpl, map[string]*bintree{}}, + "kubernetes.tmpl": {templatesKubernetesTmpl, map[string]*bintree{}}, + "kv.tmpl": {templatesKvTmpl, map[string]*bintree{}}, + "marathon.tmpl": {templatesMarathonTmpl, map[string]*bintree{}}, + "mesos.tmpl": {templatesMesosTmpl, map[string]*bintree{}}, + "notFound.tmpl": {templatesNotfoundTmpl, map[string]*bintree{}}, + "rancher.tmpl": {templatesRancherTmpl, map[string]*bintree{}}, }}, }} diff --git a/provider/consulcatalog/config.go b/provider/consulcatalog/config.go index 73d8c37e1..e4f4711a9 100644 --- a/provider/consulcatalog/config.go +++ b/provider/consulcatalog/config.go @@ -18,7 +18,7 @@ import ( "github.com/hashicorp/consul/api" ) -func (p *Provider) buildConfigurationV2(catalog []catalogUpdate) *types.Configuration { +func (p *Provider) buildConfiguration(catalog []catalogUpdate) *types.Configuration { var funcMap = template.FuncMap{ "getAttribute": p.getAttribute, "getTag": getTag, @@ -194,7 +194,8 @@ func getServerName(node *api.ServiceEntry, index int) string { } func (p *Provider) getWeight(tags []string) int { - weight := p.getIntAttribute(label.SuffixWeight, tags, label.DefaultWeight) + labels := tagsToNeutralLabels(tags, p.Prefix) + weight := label.GetIntValue(labels, p.getPrefixedName(label.SuffixWeight), label.DefaultWeight) // Deprecated deprecatedWeightTag := "backend." + label.SuffixWeight @@ -202,7 +203,7 @@ func (p *Provider) getWeight(tags []string) int { log.Warnf("Deprecated configuration found: %s. Please use %s.", p.getPrefixedName(deprecatedWeightTag), p.getPrefixedName(label.SuffixWeight)) - weight = p.getIntAttribute(deprecatedWeightTag, tags, label.DefaultWeight) + weight = label.GetIntValue(labels, p.getPrefixedName(deprecatedWeightTag), label.DefaultWeight) } return weight diff --git a/provider/consulcatalog/config_root.go b/provider/consulcatalog/config_root.go deleted file mode 100644 index fc2e14889..000000000 --- a/provider/consulcatalog/config_root.go +++ /dev/null @@ -1,10 +0,0 @@ -package consulcatalog - -import "github.com/containous/traefik/types" - -func (p *Provider) buildConfiguration(catalog []catalogUpdate) *types.Configuration { - if p.TemplateVersion == 1 { - return p.buildConfigurationV1(catalog) - } - return p.buildConfigurationV2(catalog) -} diff --git a/provider/consulcatalog/config_test.go b/provider/consulcatalog/config_test.go index 332a14dee..ad6473f04 100644 --- a/provider/consulcatalog/config_test.go +++ b/provider/consulcatalog/config_test.go @@ -708,7 +708,7 @@ func TestProviderBuildConfiguration(t *testing.T) { nodes := fakeLoadTraefikLabelsSlice(test.nodes, p.Prefix) - actualConfig := p.buildConfigurationV2(nodes) + actualConfig := p.buildConfiguration(nodes) assert.NotNil(t, actualConfig) assert.Equal(t, test.expectedBackends, actualConfig.Backends) assert.Equal(t, test.expectedFrontends, actualConfig.Frontends) diff --git a/provider/consulcatalog/deprecated_config.go b/provider/consulcatalog/deprecated_config.go deleted file mode 100644 index 618089d30..000000000 --- a/provider/consulcatalog/deprecated_config.go +++ /dev/null @@ -1,228 +0,0 @@ -package consulcatalog - -import ( - "bytes" - "sort" - "strconv" - "strings" - "text/template" - - "github.com/containous/traefik/log" - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/hashicorp/consul/api" -) - -// Deprecated -func (p *Provider) buildConfigurationV1(catalog []catalogUpdate) *types.Configuration { - var FuncMap = template.FuncMap{ - "getAttribute": p.getAttribute, - "getTag": getTag, - "hasTag": hasTag, - - // Backend functions - "getBackend": getNodeBackendName, - "getServiceBackendName": getServiceBackendName, - "getBackendAddress": getBackendAddress, - "getBackendName": getServerName, - "hasMaxconnAttributes": p.hasMaxConnAttributesV1, - "getSticky": p.getStickyV1, - "hasStickinessLabel": p.hasStickinessLabelV1, - "getStickinessCookieName": p.getStickinessCookieNameV1, - "getWeight": p.getWeight, - "getProtocol": p.getFuncStringAttribute(label.SuffixProtocol, label.DefaultProtocol), - - // Frontend functions - "getFrontendRule": p.getFrontendRuleV1, - "getBasicAuth": p.getFuncSliceAttribute(label.SuffixFrontendAuthBasic), - "getEntryPoints": getEntryPointsV1, - "getPriority": p.getFuncIntAttribute(label.SuffixFrontendPriority, label.DefaultFrontendPriority), - "getPassHostHeader": p.getFuncBoolAttribute(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeader), - "getPassTLSCert": p.getFuncBoolAttribute(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert), - } - - var allNodes []*api.ServiceEntry - var services []*serviceUpdate - for _, info := range catalog { - if len(info.Nodes) > 0 { - services = append(services, info.Service) - allNodes = append(allNodes, info.Nodes...) - } - } - // Ensure a stable ordering of nodes so that identical configurations may be detected - sort.Sort(nodeSorter(allNodes)) - - templateObjects := struct { - Services []*serviceUpdate - Nodes []*api.ServiceEntry - }{ - Services: services, - Nodes: allNodes, - } - - configuration, err := p.GetConfiguration("templates/consul_catalog-v1.tmpl", FuncMap, templateObjects) - if err != nil { - log.WithError(err).Error("Failed to create config") - } - - return configuration -} - -// Specific functions - -// Deprecated -func (p *Provider) getFrontendRuleV1(service serviceUpdate) string { - customFrontendRule := p.getAttribute(label.SuffixFrontendRule, service.Attributes, "") - if customFrontendRule == "" { - customFrontendRule = p.FrontEndRule - } - - tmpl := p.frontEndRuleTemplate - tmpl, err := tmpl.Parse(customFrontendRule) - if err != nil { - log.Errorf("Failed to parse Consul Catalog custom frontend rule: %v", err) - return "" - } - - templateObjects := struct { - ServiceName string - Domain string - Attributes []string - }{ - ServiceName: service.ServiceName, - Domain: p.Domain, - Attributes: service.Attributes, - } - - var buffer bytes.Buffer - err = tmpl.Execute(&buffer, templateObjects) - if err != nil { - log.Errorf("Failed to execute Consul Catalog custom frontend rule template: %v", err) - return "" - } - - return buffer.String() -} - -// Deprecated -func (p *Provider) hasMaxConnAttributesV1(attributes []string) bool { - amount := p.getAttribute(label.SuffixBackendMaxConnAmount, attributes, "") - extractorFunc := p.getAttribute(label.SuffixBackendMaxConnExtractorFunc, attributes, "") - return amount != "" && extractorFunc != "" -} - -// Deprecated -func getEntryPointsV1(list string) []string { - return strings.Split(list, ",") -} - -// TODO: Deprecated -// replaced by Stickiness -// Deprecated -func (p *Provider) getStickyV1(tags []string) string { - stickyTag := p.getAttribute(label.SuffixBackendLoadBalancerSticky, tags, "") - if len(stickyTag) > 0 { - log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness) - } else { - stickyTag = "false" - } - return stickyTag -} - -// Deprecated -func (p *Provider) hasStickinessLabelV1(tags []string) bool { - stickinessTag := p.getAttribute(label.SuffixBackendLoadBalancerStickiness, tags, "") - return len(stickinessTag) > 0 && strings.EqualFold(strings.TrimSpace(stickinessTag), "true") -} - -// Deprecated -func (p *Provider) getStickinessCookieNameV1(tags []string) string { - return p.getAttribute(label.SuffixBackendLoadBalancerStickinessCookieName, tags, "") -} - -// Base functions - -// Deprecated -func (p *Provider) getFuncStringAttribute(name string, defaultValue string) func(tags []string) string { - return func(tags []string) string { - return p.getAttribute(name, tags, defaultValue) - } -} - -// Deprecated -func (p *Provider) getFuncSliceAttribute(name string) func(tags []string) []string { - return func(tags []string) []string { - return p.getSliceAttribute(name, tags) - } -} - -// Deprecated -func (p *Provider) getFuncIntAttribute(name string, defaultValue int) func(tags []string) int { - return func(tags []string) int { - return p.getIntAttribute(name, tags, defaultValue) - } -} - -func (p *Provider) getFuncBoolAttribute(name string, defaultValue bool) func(tags []string) bool { - return func(tags []string) bool { - return p.getBoolAttribute(name, tags, defaultValue) - } -} - -// Deprecated -func (p *Provider) getInt64Attribute(name string, tags []string, defaultValue int64) int64 { - rawValue := getTag(p.getPrefixedName(name), tags, "") - - if len(rawValue) == 0 { - return defaultValue - } - - value, err := strconv.ParseInt(rawValue, 10, 64) - if err != nil { - log.Errorf("Invalid value for %s: %s", name, rawValue) - return defaultValue - } - return value -} - -// Deprecated -func (p *Provider) getIntAttribute(name string, tags []string, defaultValue int) int { - rawValue := getTag(p.getPrefixedName(name), tags, "") - - if len(rawValue) == 0 { - return defaultValue - } - - value, err := strconv.Atoi(rawValue) - if err != nil { - log.Errorf("Invalid value for %s: %s", name, rawValue) - return defaultValue - } - return value -} - -// Deprecated -func (p *Provider) getSliceAttribute(name string, tags []string) []string { - rawValue := getTag(p.getPrefixedName(name), tags, "") - - if len(rawValue) == 0 { - return nil - } - return label.SplitAndTrimString(rawValue, ",") -} - -// Deprecated -func (p *Provider) getBoolAttribute(name string, tags []string, defaultValue bool) bool { - rawValue := getTag(p.getPrefixedName(name), tags, "") - - if len(rawValue) == 0 { - return defaultValue - } - - value, err := strconv.ParseBool(rawValue) - if err != nil { - log.Errorf("Invalid value for %s: %s", name, rawValue) - return defaultValue - } - return value -} diff --git a/provider/consulcatalog/deprecated_config_test.go b/provider/consulcatalog/deprecated_config_test.go deleted file mode 100644 index a5415a425..000000000 --- a/provider/consulcatalog/deprecated_config_test.go +++ /dev/null @@ -1,444 +0,0 @@ -package consulcatalog - -import ( - "testing" - "text/template" - - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/hashicorp/consul/api" - "github.com/stretchr/testify/assert" -) - -func TestProviderBuildConfigurationV1(t *testing.T) { - p := &Provider{ - Domain: "localhost", - Prefix: "traefik", - ExposedByDefault: false, - FrontEndRule: "Host:{{.ServiceName}}.{{.Domain}}", - frontEndRuleTemplate: template.New("consul catalog frontend rule"), - } - - testCases := []struct { - desc string - nodes []catalogUpdate - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - }{ - { - desc: "Should build config of nothing", - nodes: []catalogUpdate{}, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - }, - { - desc: "Should build config with no frontend and backend", - nodes: []catalogUpdate{ - { - Service: &serviceUpdate{ - ServiceName: "test", - }, - }, - }, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - }, - { - desc: "Should build config who contains one frontend and one backend", - nodes: []catalogUpdate{ - { - Service: &serviceUpdate{ - ServiceName: "test", - Attributes: []string{ - "random.foo=bar", - label.TraefikBackendLoadBalancer + "=drr", - label.TraefikBackendCircuitBreaker + "=NetworkErrorRatio() > 0.5", - label.TraefikBackendMaxConnAmount + "=1000", - label.TraefikBackendMaxConnExtractorFunc + "=client.ip", - label.TraefikFrontendAuthBasic + "=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - Nodes: []*api.ServiceEntry{ - { - Service: &api.AgentService{ - Service: "test", - Address: "127.0.0.1", - Port: 80, - Tags: []string{ - "random.foo=bar", - label.Prefix + "backend.weight=42", - label.TraefikFrontendPassHostHeader + "=true", - label.TraefikProtocol + "=https", - }, - }, - Node: &api.Node{ - Node: "localhost", - Address: "127.0.0.1", - }, - }, - }, - }, - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-test": { - Backend: "backend-test", - PassHostHeader: true, - Routes: map[string]types.Route{ - "route-host-test": { - Rule: "Host:test.localhost", - }, - }, - BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-test": { - Servers: map[string]types.Server{ - "test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": { - URL: "https://127.0.0.1:80", - Weight: 42, - }, - }, - CircuitBreaker: &types.CircuitBreaker{ - Expression: "NetworkErrorRatio() > 0.5", - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - }, - MaxConn: &types.MaxConn{ - Amount: 1000, - ExtractorFunc: "client.ip", - }, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actualConfig := p.buildConfigurationV1(test.nodes) - assert.NotNil(t, actualConfig) - assert.Equal(t, test.expectedBackends, actualConfig.Backends) - assert.Equal(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestProviderGetIntAttributeV1(t *testing.T) { - p := &Provider{ - Prefix: "traefik", - } - - testCases := []struct { - desc string - name string - tags []string - defaultValue int - expected int - }{ - { - desc: "should return default value when empty name", - name: "", - tags: []string{"traefik.foo=10"}, - defaultValue: 666, - expected: 666, - }, - { - desc: "should return default value when empty tags", - name: "traefik.foo", - tags: nil, - expected: 0, - }, - { - desc: "should return default value when value is not a int", - name: "foo", - tags: []string{"traefik.foo=bar"}, - expected: 0, - }, - { - desc: "should return a value when tag exist", - name: "foo", - tags: []string{"traefik.foo=10"}, - expected: 10, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - result := p.getIntAttribute(test.name, test.tags, test.defaultValue) - - assert.Equal(t, test.expected, result) - }) - } -} - -func TestProviderGetInt64AttributeV1(t *testing.T) { - p := &Provider{ - Prefix: "traefik", - } - - testCases := []struct { - desc string - name string - tags []string - defaultValue int64 - expected int64 - }{ - { - desc: "should return default value when empty name", - name: "", - tags: []string{"traefik.foo=10"}, - defaultValue: 666, - expected: 666, - }, - { - desc: "should return default value when empty tags", - name: "traefik.foo", - tags: nil, - expected: 0, - }, - { - desc: "should return default value when value is not a int", - name: "foo", - tags: []string{"traefik.foo=bar"}, - expected: 0, - }, - { - desc: "should return a value when tag exist", - name: "foo", - tags: []string{"traefik.foo=10"}, - expected: 10, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - result := p.getInt64Attribute(test.name, test.tags, test.defaultValue) - - assert.Equal(t, test.expected, result) - }) - } -} - -func TestProviderGetBoolAttributeV1(t *testing.T) { - p := &Provider{ - Prefix: "traefik", - } - - testCases := []struct { - desc string - name string - tags []string - defaultValue bool - expected bool - }{ - { - desc: "should return default value when empty name", - name: "", - tags: []string{"traefik.foo=true"}, - defaultValue: true, - expected: true, - }, - { - desc: "should return default value when empty tags", - name: "traefik.foo", - tags: nil, - expected: false, - }, - { - desc: "should return default value when value is not a bool", - name: "foo", - tags: []string{"traefik.foo=bar"}, - expected: false, - }, - { - desc: "should return a value when tag exist", - name: "foo", - tags: []string{"traefik.foo=true"}, - expected: true, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - result := p.getBoolAttribute(test.name, test.tags, test.defaultValue) - - assert.Equal(t, test.expected, result) - }) - } -} - -func TestProviderGetSliceAttributeV1(t *testing.T) { - p := &Provider{ - Prefix: "traefik", - } - - testCases := []struct { - desc string - name string - tags []string - expected []string - }{ - { - desc: "should return nil when empty name", - name: "", - tags: []string{"traefik.foo=bar,bor,bir"}, - expected: nil, - }, - { - desc: "should return nil when empty tags", - name: "foo", - tags: nil, - expected: nil, - }, - { - desc: "should return nil when tag doesn't have value", - name: "", - tags: []string{"traefik.foo="}, - expected: nil, - }, - { - desc: "should return a slice when tag contains comma separated values", - name: "foo", - tags: []string{"traefik.foo=bar,bor,bir"}, - expected: []string{"bar", "bor", "bir"}, - }, - { - desc: "should return a slice when tag contains one value", - name: "foo", - tags: []string{"traefik.foo=bar"}, - expected: []string{"bar"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - result := p.getSliceAttribute(test.name, test.tags) - - assert.Equal(t, test.expected, result) - }) - } -} - -func TestProviderGetFrontendRuleV1(t *testing.T) { - testCases := []struct { - desc string - service serviceUpdate - expected string - }{ - { - desc: "Should return default host foo.localhost", - service: serviceUpdate{ - ServiceName: "foo", - Attributes: []string{}, - }, - expected: "Host:foo.localhost", - }, - { - desc: "Should return host *.example.com", - service: serviceUpdate{ - ServiceName: "foo", - Attributes: []string{ - "traefik.frontend.rule=Host:*.example.com", - }, - }, - expected: "Host:*.example.com", - }, - { - desc: "Should return host foo.example.com", - service: serviceUpdate{ - ServiceName: "foo", - Attributes: []string{ - "traefik.frontend.rule=Host:{{.ServiceName}}.example.com", - }, - }, - expected: "Host:foo.example.com", - }, - { - desc: "Should return path prefix /bar", - service: serviceUpdate{ - ServiceName: "foo", - Attributes: []string{ - "traefik.frontend.rule=PathPrefix:{{getTag \"contextPath\" .Attributes \"/\"}}", - "contextPath=/bar", - }, - }, - expected: "PathPrefix:/bar", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - p := &Provider{ - Domain: "localhost", - Prefix: "traefik", - FrontEndRule: "Host:{{.ServiceName}}.{{.Domain}}", - frontEndRuleTemplate: template.New("consul catalog frontend rule"), - } - p.setupFrontEndRuleTemplate() - - actual := p.getFrontendRuleV1(test.service) - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestHasStickinessLabelV1(t *testing.T) { - p := &Provider{ - Prefix: "traefik", - } - - testCases := []struct { - desc string - tags []string - expected bool - }{ - { - desc: "label missing", - tags: []string{}, - expected: false, - }, - { - desc: "stickiness=true", - tags: []string{ - label.TraefikBackendLoadBalancerStickiness + "=true", - }, - expected: true, - }, - { - desc: "stickiness=false", - tags: []string{ - label.TraefikBackendLoadBalancerStickiness + "=false", - }, - expected: false, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := p.hasStickinessLabelV1(test.tags) - assert.Equal(t, test.expected, actual) - }) - } -} diff --git a/provider/docker/config.go b/provider/docker/config.go index 546e34c1e..8b5e2d674 100644 --- a/provider/docker/config.go +++ b/provider/docker/config.go @@ -25,7 +25,7 @@ const ( labelDockerComposeService = "com.docker.compose.service" ) -func (p *Provider) buildConfigurationV2(containersInspected []dockerData) *types.Configuration { +func (p *Provider) buildConfiguration(containersInspected []dockerData) *types.Configuration { dockerFuncMap := template.FuncMap{ "getLabelValue": label.GetStringValue, "getSubDomain": getSubDomain, diff --git a/provider/docker/config_container_docker_test.go b/provider/docker/config_container_docker_test.go index 6e340c74a..660907d5c 100644 --- a/provider/docker/config_container_docker_test.go +++ b/provider/docker/config_container_docker_test.go @@ -713,7 +713,7 @@ func TestDockerBuildConfiguration(t *testing.T) { ExposedByDefault: true, Network: "webnet", } - actualConfig := provider.buildConfigurationV2(dockerDataList) + actualConfig := provider.buildConfiguration(dockerDataList) require.NotNil(t, actualConfig, "actualConfig") assert.EqualValues(t, test.expectedBackends, actualConfig.Backends) diff --git a/provider/docker/config_container_swarm_test.go b/provider/docker/config_container_swarm_test.go index a8cbdca4e..613871bda 100644 --- a/provider/docker/config_container_swarm_test.go +++ b/provider/docker/config_container_swarm_test.go @@ -571,7 +571,7 @@ func TestSwarmBuildConfiguration(t *testing.T) { SwarmMode: true, } - actualConfig := provider.buildConfigurationV2(dockerDataList) + actualConfig := provider.buildConfiguration(dockerDataList) require.NotNil(t, actualConfig, "actualConfig") assert.EqualValues(t, test.expectedBackends, actualConfig.Backends) diff --git a/provider/docker/config_root.go b/provider/docker/config_root.go deleted file mode 100644 index 5819e49a4..000000000 --- a/provider/docker/config_root.go +++ /dev/null @@ -1,12 +0,0 @@ -package docker - -import ( - "github.com/containous/traefik/types" -) - -func (p *Provider) buildConfiguration(containersInspected []dockerData) *types.Configuration { - if p.TemplateVersion == 1 { - return p.buildConfigurationV1(containersInspected) - } - return p.buildConfigurationV2(containersInspected) -} diff --git a/provider/docker/config_segment_test.go b/provider/docker/config_segment_test.go index 1452b5fb3..3cd439d70 100644 --- a/provider/docker/config_segment_test.go +++ b/provider/docker/config_segment_test.go @@ -721,7 +721,7 @@ func TestSegmentBuildConfiguration(t *testing.T) { dockerDataList = append(dockerDataList, dData) } - actualConfig := provider.buildConfigurationV2(dockerDataList) + actualConfig := provider.buildConfiguration(dockerDataList) require.NotNil(t, actualConfig, "actualConfig") assert.EqualValues(t, test.expectedBackends, actualConfig.Backends) diff --git a/provider/docker/deprecated_config.go b/provider/docker/deprecated_config.go deleted file mode 100644 index 32f90c1f6..000000000 --- a/provider/docker/deprecated_config.go +++ /dev/null @@ -1,263 +0,0 @@ -package docker - -import ( - "context" - "math" - "strconv" - "strings" - "text/template" - - "github.com/BurntSushi/ty/fun" - "github.com/containous/traefik/log" - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" -) - -// Deprecated -func (p *Provider) buildConfigurationV1(containersInspected []dockerData) *types.Configuration { - var DockerFuncMap = template.FuncMap{ - "getDomain": getFuncStringLabelV1(label.TraefikDomain, p.Domain), - "getSubDomain": getSubDomain, - "isBackendLBSwarm": isBackendLBSwarm, - - // Backend functions - "getIPAddress": p.getIPAddressV1, - "getPort": getPortV1, - "getWeight": getFuncIntLabelV1(label.TraefikWeight, label.DefaultWeight), - "getProtocol": getFuncStringLabelV1(label.TraefikProtocol, label.DefaultProtocol), - - "hasCircuitBreakerLabel": hasFuncV1(label.TraefikBackendCircuitBreakerExpression), - "getCircuitBreakerExpression": getFuncStringLabelV1(label.TraefikBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression), - "hasLoadBalancerLabel": hasLoadBalancerLabelV1, - "getLoadBalancerMethod": getFuncStringLabelV1(label.TraefikBackendLoadBalancerMethod, label.DefaultBackendLoadBalancerMethod), - "hasMaxConnLabels": hasMaxConnLabelsV1, - "getMaxConnAmount": getFuncInt64LabelV1(label.TraefikBackendMaxConnAmount, math.MaxInt64), - "getMaxConnExtractorFunc": getFuncStringLabelV1(label.TraefikBackendMaxConnExtractorFunc, label.DefaultBackendMaxconnExtractorFunc), - "getSticky": getStickyV1, - "hasStickinessLabel": hasFuncV1(label.TraefikBackendLoadBalancerStickiness), - "getStickinessCookieName": getFuncStringLabelV1(label.TraefikBackendLoadBalancerStickinessCookieName, label.DefaultBackendLoadbalancerStickinessCookieName), - - // Frontend functions - "getBackend": getBackendNameV1, - "getBackendName": getBackendNameV1, - "getPriority": getFuncIntLabelV1(label.TraefikFrontendPriority, label.DefaultFrontendPriority), - "getPassHostHeader": getFuncBoolLabelV1(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), - "getPassTLSCert": getFuncBoolLabelV1(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), - "getEntryPoints": getFuncSliceStringLabelV1(label.TraefikFrontendEntryPoints), - "getBasicAuth": getFuncSliceStringLabelV1(label.TraefikFrontendAuthBasic), - "getWhitelistSourceRange": getFuncSliceStringLabelV1(label.TraefikFrontendWhitelistSourceRange), - "getFrontendRule": p.getFrontendRuleV1, - "hasRedirect": hasRedirectV1, - "getRedirectEntryPoint": getFuncStringLabelV1(label.TraefikFrontendRedirectEntryPoint, ""), - "getRedirectRegex": getFuncStringLabelV1(label.TraefikFrontendRedirectRegex, ""), - "getRedirectReplacement": getFuncStringLabelV1(label.TraefikFrontendRedirectReplacement, ""), - - "hasHeaders": hasHeadersV1, - "hasRequestHeaders": hasLabelV1(label.TraefikFrontendRequestHeaders), - "getRequestHeaders": getFuncMapLabelV1(label.TraefikFrontendRequestHeaders), - "hasResponseHeaders": hasLabelV1(label.TraefikFrontendResponseHeaders), - "getResponseHeaders": getFuncMapLabelV1(label.TraefikFrontendResponseHeaders), - "hasAllowedHostsHeaders": hasLabelV1(label.TraefikFrontendAllowedHosts), - "getAllowedHostsHeaders": getFuncSliceStringLabelV1(label.TraefikFrontendAllowedHosts), - "hasHostsProxyHeaders": hasLabelV1(label.TraefikFrontendHostsProxyHeaders), - "getHostsProxyHeaders": getFuncSliceStringLabelV1(label.TraefikFrontendHostsProxyHeaders), - "hasSSLRedirectHeaders": hasLabelV1(label.TraefikFrontendSSLRedirect), - "getSSLRedirectHeaders": getFuncBoolLabelV1(label.TraefikFrontendSSLRedirect, false), - "hasSSLTemporaryRedirectHeaders": hasLabelV1(label.TraefikFrontendSSLTemporaryRedirect), - "getSSLTemporaryRedirectHeaders": getFuncBoolLabelV1(label.TraefikFrontendSSLTemporaryRedirect, false), - "hasSSLHostHeaders": hasLabelV1(label.TraefikFrontendSSLHost), - "getSSLHostHeaders": getFuncStringLabelV1(label.TraefikFrontendSSLHost, ""), - "hasSSLProxyHeaders": hasLabelV1(label.TraefikFrontendSSLProxyHeaders), - "getSSLProxyHeaders": getFuncMapLabelV1(label.TraefikFrontendSSLProxyHeaders), - "hasSTSSecondsHeaders": hasLabelV1(label.TraefikFrontendSTSSeconds), - "getSTSSecondsHeaders": getFuncInt64LabelV1(label.TraefikFrontendSTSSeconds, 0), - "hasSTSIncludeSubdomainsHeaders": hasLabelV1(label.TraefikFrontendSTSIncludeSubdomains), - "getSTSIncludeSubdomainsHeaders": getFuncBoolLabelV1(label.TraefikFrontendSTSIncludeSubdomains, false), - "hasSTSPreloadHeaders": hasLabelV1(label.TraefikFrontendSTSPreload), - "getSTSPreloadHeaders": getFuncBoolLabelV1(label.TraefikFrontendSTSPreload, false), - "hasForceSTSHeaderHeaders": hasLabelV1(label.TraefikFrontendForceSTSHeader), - "getForceSTSHeaderHeaders": getFuncBoolLabelV1(label.TraefikFrontendForceSTSHeader, false), - "hasFrameDenyHeaders": hasLabelV1(label.TraefikFrontendFrameDeny), - "getFrameDenyHeaders": getFuncBoolLabelV1(label.TraefikFrontendFrameDeny, false), - "hasCustomFrameOptionsValueHeaders": hasLabelV1(label.TraefikFrontendCustomFrameOptionsValue), - "getCustomFrameOptionsValueHeaders": getFuncStringLabelV1(label.TraefikFrontendCustomFrameOptionsValue, ""), - "hasContentTypeNosniffHeaders": hasLabelV1(label.TraefikFrontendContentTypeNosniff), - "getContentTypeNosniffHeaders": getFuncBoolLabelV1(label.TraefikFrontendContentTypeNosniff, false), - "hasBrowserXSSFilterHeaders": hasLabelV1(label.TraefikFrontendBrowserXSSFilter), - "getBrowserXSSFilterHeaders": getFuncBoolLabelV1(label.TraefikFrontendBrowserXSSFilter, false), - "hasContentSecurityPolicyHeaders": hasLabelV1(label.TraefikFrontendContentSecurityPolicy), - "getContentSecurityPolicyHeaders": getFuncStringLabelV1(label.TraefikFrontendContentSecurityPolicy, ""), - "hasPublicKeyHeaders": hasLabelV1(label.TraefikFrontendPublicKey), - "getPublicKeyHeaders": getFuncStringLabelV1(label.TraefikFrontendPublicKey, ""), - "hasReferrerPolicyHeaders": hasLabelV1(label.TraefikFrontendReferrerPolicy), - "getReferrerPolicyHeaders": getFuncStringLabelV1(label.TraefikFrontendReferrerPolicy, ""), - "hasIsDevelopmentHeaders": hasLabelV1(label.TraefikFrontendIsDevelopment), - "getIsDevelopmentHeaders": getFuncBoolLabelV1(label.TraefikFrontendIsDevelopment, false), - - // Services - "hasServices": hasServicesV1, - "getServiceNames": getServiceNamesV1, - "getServiceBackend": getServiceBackendNameV1, - "getServiceBackendName": getServiceBackendNameV1, - // Services - Backend server functions - "getServicePort": getServicePortV1, - "getServiceProtocol": getFuncServiceStringLabelV1(label.SuffixProtocol, label.DefaultProtocol), - "getServiceWeight": getFuncServiceIntLabelV1(label.SuffixWeight, label.DefaultWeight), - // Services - Frontend functions - "getServiceEntryPoints": getFuncServiceSliceStringLabelV1(label.SuffixFrontendEntryPoints), - "getServiceWhitelistSourceRange": getFuncServiceSliceStringLabelV1(label.SuffixFrontendWhiteListSourceRange), - "getServiceBasicAuth": getFuncServiceSliceStringLabelV1(label.SuffixFrontendAuthBasic), - "getServiceFrontendRule": p.getServiceFrontendRuleV1, - "getServicePassHostHeader": getFuncServiceBoolLabelV1(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeader), - "getServicePassTLSCert": getFuncServiceBoolLabelV1(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert), - "getServicePriority": getFuncServiceIntLabelV1(label.SuffixFrontendPriority, label.DefaultFrontendPriority), - "hasServiceRedirect": hasServiceRedirectV1, - "getServiceRedirectEntryPoint": getFuncServiceStringLabelV1(label.SuffixFrontendRedirectEntryPoint, ""), - "getServiceRedirectReplacement": getFuncServiceStringLabelV1(label.SuffixFrontendRedirectReplacement, ""), - "getServiceRedirectRegex": getFuncServiceStringLabelV1(label.SuffixFrontendRedirectRegex, ""), - } - - // filter containers - filteredContainers := fun.Filter(func(container dockerData) bool { - return p.containerFilterV1(container) - }, containersInspected).([]dockerData) - - frontends := map[string][]dockerData{} - backends := map[string]dockerData{} - servers := map[string][]dockerData{} - serviceNames := make(map[string]struct{}) - for idx, container := range filteredContainers { - - serviceNamesKey := getServiceNameKey(container, p.SwarmMode, "") - - if _, exists := serviceNames[serviceNamesKey]; !exists { - frontendName := p.getFrontendNameV1(container, idx) - frontends[frontendName] = append(frontends[frontendName], container) - if len(serviceNamesKey) > 0 { - serviceNames[serviceNamesKey] = struct{}{} - } - } - backendName := getBackendNameV1(container) - backends[backendName] = container - servers[backendName] = append(servers[backendName], container) - } - - templateObjects := struct { - Containers []dockerData - Frontends map[string][]dockerData - Backends map[string]dockerData - Servers map[string][]dockerData - Domain string - }{ - Containers: filteredContainers, - Frontends: frontends, - Backends: backends, - Servers: servers, - Domain: p.Domain, - } - - configuration, err := p.GetConfiguration("templates/docker-v1.tmpl", DockerFuncMap, templateObjects) - if err != nil { - log.Error(err) - } - - return configuration -} - -// Deprecated -func (p Provider) containerFilterV1(container dockerData) bool { - if !label.IsEnabled(container.Labels, p.ExposedByDefault) { - log.Debugf("Filtering disabled container %s", container.Name) - return false - } - - var err error - portLabel := "traefik.port label" - if hasServicesV1(container) { - portLabel = "traefik..port or " + portLabel + "s" - err = checkServiceLabelPortV1(container) - } else { - _, err = strconv.Atoi(container.Labels[label.TraefikPort]) - } - if len(container.NetworkSettings.Ports) == 0 && err != nil { - log.Debugf("Filtering container without port and no %s %s : %s", portLabel, container.Name, err.Error()) - return false - } - - constraintTags := label.SplitAndTrimString(container.Labels[label.TraefikTags], ",") - if ok, failingConstraint := p.MatchConstraints(constraintTags); !ok { - if failingConstraint != nil { - log.Debugf("Container %v pruned by '%v' constraint", container.Name, failingConstraint.String()) - } - return false - } - - if container.Health != "" && container.Health != "healthy" { - log.Debugf("Filtering unhealthy or starting container %s", container.Name) - return false - } - - if len(p.getFrontendRuleV1(container)) == 0 { - log.Debugf("Filtering container with empty frontend rule %s", container.Name) - return false - } - - return true -} - -func (p Provider) getIPAddressV1(container dockerData) string { - if value := label.GetStringValue(container.Labels, labelDockerNetwork, p.Network); value != "" { - networkSettings := container.NetworkSettings - if networkSettings.Networks != nil { - network := networkSettings.Networks[value] - if network != nil { - return network.Addr - } - - log.Warnf("Could not find network named '%s' for container '%s'! Maybe you're missing the project's prefix in the label? Defaulting to first available network.", value, container.Name) - } - } - - if container.NetworkSettings.NetworkMode.IsHost() { - if container.Node != nil { - if container.Node.IPAddress != "" { - return container.Node.IPAddress - } - } - return "127.0.0.1" - } - - if container.NetworkSettings.NetworkMode.IsContainer() { - dockerClient, err := p.createClient() - if err != nil { - log.Warnf("Unable to get IP address for container %s, error: %s", container.Name, err) - return "" - } - - connectedContainer := container.NetworkSettings.NetworkMode.ConnectedContainer() - containerInspected, err := dockerClient.ContainerInspect(context.Background(), connectedContainer) - if err != nil { - log.Warnf("Unable to get IP address for container %s : Failed to inspect container ID %s, error: %s", container.Name, connectedContainer, err) - return "" - } - return p.getIPAddress(parseContainer(containerInspected)) - } - - if p.UseBindPortIP { - port := getPortV1(container) - for netPort, portBindings := range container.NetworkSettings.Ports { - if strings.EqualFold(string(netPort), port+"/TCP") || strings.EqualFold(string(netPort), port+"/UDP") { - for _, p := range portBindings { - return p.HostIP - } - } - } - } - - for _, network := range container.NetworkSettings.Networks { - return network.Addr - } - - log.Warnf("Unable to find the IP address for the container %q.", container.Name) - return "" -} diff --git a/provider/docker/deprecated_container.go b/provider/docker/deprecated_container.go deleted file mode 100644 index a05af3d60..000000000 --- a/provider/docker/deprecated_container.go +++ /dev/null @@ -1,216 +0,0 @@ -package docker - -import ( - "fmt" - "net/http" - "strconv" - "strings" - - "github.com/containous/traefik/log" - "github.com/containous/traefik/provider" - "github.com/containous/traefik/provider/label" - "github.com/docker/go-connections/nat" -) - -// Specific functions - -// Deprecated -func (p Provider) getFrontendNameV1(container dockerData, idx int) string { - return provider.Normalize(p.getFrontendRuleV1(container) + "-" + strconv.Itoa(idx)) -} - -// GetFrontendRule returns the frontend rule for the specified container, using -// it's label. It returns a default one (Host) if the label is not present. -// Deprecated -func (p Provider) getFrontendRuleV1(container dockerData) string { - if value := label.GetStringValue(container.Labels, label.TraefikFrontendRule, ""); len(value) != 0 { - return value - } - - domain := label.GetStringValue(container.Labels, label.TraefikDomain, p.Domain) - - if values, err := label.GetStringMultipleStrict(container.Labels, labelDockerComposeProject, labelDockerComposeService); err == nil { - return "Host:" + getSubDomain(values[labelDockerComposeService]+"."+values[labelDockerComposeProject]) + "." + domain - } - - if len(domain) > 0 { - return "Host:" + getSubDomain(container.ServiceName) + "." + domain - } - - return "" -} - -// Deprecated -func getBackendNameV1(container dockerData) string { - if value := label.GetStringValue(container.Labels, label.TraefikBackend, ""); len(value) != 0 { - return provider.Normalize(value) - } - - if values, err := label.GetStringMultipleStrict(container.Labels, labelDockerComposeProject, labelDockerComposeService); err == nil { - return provider.Normalize(values[labelDockerComposeService] + "_" + values[labelDockerComposeProject]) - } - - return provider.Normalize(container.ServiceName) -} - -// Deprecated -func getPortV1(container dockerData) string { - if value := label.GetStringValue(container.Labels, label.TraefikPort, ""); len(value) != 0 { - return value - } - - // See iteration order in https://blog.golang.org/go-maps-in-action - var ports []nat.Port - for port := range container.NetworkSettings.Ports { - ports = append(ports, port) - } - - less := func(i, j nat.Port) bool { - return i.Int() < j.Int() - } - nat.Sort(ports, less) - - if len(ports) > 0 { - min := ports[0] - return min.Port() - } - - return "" -} - -// replaced by Stickiness -// Deprecated -func getStickyV1(container dockerData) bool { - if label.Has(container.Labels, label.TraefikBackendLoadBalancerSticky) { - log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness) - } - - return label.GetBoolValue(container.Labels, label.TraefikBackendLoadBalancerSticky, false) -} - -// Deprecated -func hasLoadBalancerLabelV1(container dockerData) bool { - method := label.Has(container.Labels, label.TraefikBackendLoadBalancerMethod) - sticky := label.Has(container.Labels, label.TraefikBackendLoadBalancerSticky) - stickiness := label.Has(container.Labels, label.TraefikBackendLoadBalancerStickiness) - cookieName := label.Has(container.Labels, label.TraefikBackendLoadBalancerStickinessCookieName) - return method || sticky || stickiness || cookieName -} - -// Deprecated -func hasMaxConnLabelsV1(container dockerData) bool { - mca := label.Has(container.Labels, label.TraefikBackendMaxConnAmount) - mcef := label.Has(container.Labels, label.TraefikBackendMaxConnExtractorFunc) - return mca && mcef -} - -// Deprecated -func hasRedirectV1(container dockerData) bool { - return hasLabelV1(label.TraefikFrontendRedirectEntryPoint)(container) || - hasLabelV1(label.TraefikFrontendRedirectReplacement)(container) && hasLabelV1(label.TraefikFrontendRedirectRegex)(container) -} - -// Deprecated -func hasHeadersV1(container dockerData) bool { - for key := range container.Labels { - if strings.HasPrefix(key, label.Prefix+"frontend.headers.") { - return true - } - } - return false -} - -// Label functions - -// Deprecated -func getFuncStringLabelV1(labelName string, defaultValue string) func(container dockerData) string { - return func(container dockerData) string { - return label.GetStringValue(container.Labels, labelName, defaultValue) - } -} - -// Deprecated -func getFuncBoolLabelV1(labelName string, defaultValue bool) func(container dockerData) bool { - return func(container dockerData) bool { - return label.GetBoolValue(container.Labels, labelName, defaultValue) - } -} - -// Deprecated -func getFuncSliceStringLabelV1(labelName string) func(container dockerData) []string { - return func(container dockerData) []string { - return label.GetSliceStringValue(container.Labels, labelName) - } -} - -// Deprecated -func getFuncIntLabelV1(labelName string, defaultValue int) func(container dockerData) int { - return func(container dockerData) int { - return label.GetIntValue(container.Labels, labelName, defaultValue) - } -} - -// Deprecated -func getFuncInt64LabelV1(labelName string, defaultValue int64) func(container dockerData) int64 { - return func(container dockerData) int64 { - return label.GetInt64Value(container.Labels, labelName, defaultValue) - } -} - -// Deprecated -func hasFuncV1(labelName string) func(container dockerData) bool { - return func(container dockerData) bool { - return label.Has(container.Labels, labelName) - } -} - -// Deprecated -func hasLabelV1(label string) func(container dockerData) bool { - return func(container dockerData) bool { - lbl, err := getLabelV1(container, label) - return err == nil && len(lbl) > 0 - } -} - -// Deprecated -func getLabelV1(container dockerData, label string) (string, error) { - if value, ok := container.Labels[label]; ok { - return value, nil - } - return "", fmt.Errorf("label not found: %s", label) -} - -// Deprecated -func getFuncMapLabelV1(labelName string) func(container dockerData) map[string]string { - return func(container dockerData) map[string]string { - return parseMapLabelV1(container, labelName) - } -} - -// Deprecated -func parseMapLabelV1(container dockerData, labelName string) map[string]string { - if parts, err := getLabelV1(container, labelName); err == nil { - if len(parts) == 0 { - log.Errorf("Could not load %q", labelName) - return nil - } - - values := make(map[string]string) - for _, headers := range strings.Split(parts, "||") { - pair := strings.SplitN(headers, ":", 2) - if len(pair) != 2 { - log.Warnf("Could not load %q: %v, skipping...", labelName, pair) - } else { - values[http.CanonicalHeaderKey(strings.TrimSpace(pair[0]))] = strings.TrimSpace(pair[1]) - } - } - - if len(values) == 0 { - log.Errorf("Could not load %q", labelName) - return nil - } - return values - } - - return nil -} diff --git a/provider/docker/deprecated_container_docker_test.go b/provider/docker/deprecated_container_docker_test.go deleted file mode 100644 index b7359980c..000000000 --- a/provider/docker/deprecated_container_docker_test.go +++ /dev/null @@ -1,969 +0,0 @@ -package docker - -import ( - "reflect" - "strconv" - "testing" - - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - docker "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestDockerBuildConfigurationV1(t *testing.T) { - testCases := []struct { - desc string - containers []docker.ContainerJSON - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - }{ - { - desc: "when no container", - containers: []docker.ContainerJSON{}, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - }, - { - desc: "when basic container configuration", - containers: []docker.ContainerJSON{ - containerJSON( - name("test"), - ports(nat.PortMap{ - "80/tcp": {}, - }), - withNetwork("bridge", ipv4("127.0.0.1")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-Host-test-docker-localhost-0": { - Backend: "backend-test", - PassHostHeader: true, - EntryPoints: []string{}, - BasicAuth: []string{}, - Routes: map[string]types.Route{ - "route-frontend-Host-test-docker-localhost-0": { - Rule: "Host:test.docker.localhost", - }, - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-test": { - Servers: map[string]types.Server{ - "server-test": { - URL: "http://127.0.0.1:80", - Weight: label.DefaultWeight, - }, - }, - CircuitBreaker: nil, - }, - }, - }, - { - desc: "when container has label 'enable' to false", - containers: []docker.ContainerJSON{ - containerJSON( - name("test"), - labels(map[string]string{ - label.TraefikEnable: "false", - label.TraefikPort: "666", - label.TraefikProtocol: "https", - label.TraefikWeight: "12", - label.TraefikBackend: "foobar", - }), - ports(nat.PortMap{ - "80/tcp": {}, - }), - withNetwork("bridge", ipv4("127.0.0.1")), - ), - }, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - }, - { - desc: "when all labels are set", - containers: []docker.ContainerJSON{ - containerJSON( - name("test1"), - labels(map[string]string{ - label.TraefikPort: "666", - label.TraefikProtocol: "https", - label.TraefikWeight: "12", - - label.TraefikBackend: "foobar", - - label.TraefikBackendCircuitBreakerExpression: "NetworkErrorRatio() > 0.5", - label.TraefikBackendLoadBalancerMethod: "drr", - label.TraefikBackendLoadBalancerSticky: "true", - label.TraefikBackendLoadBalancerStickiness: "true", - label.TraefikBackendLoadBalancerStickinessCookieName: "chocolate", - label.TraefikBackendMaxConnAmount: "666", - label.TraefikBackendMaxConnExtractorFunc: "client.ip", - - label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - label.TraefikFrontendEntryPoints: "http,https", - label.TraefikFrontendPassHostHeader: "true", - label.TraefikFrontendPassTLSCert: "true", - label.TraefikFrontendPriority: "666", - label.TraefikFrontendRedirectEntryPoint: "https", - label.TraefikFrontendRedirectRegex: "nope", - label.TraefikFrontendRedirectReplacement: "nope", - label.TraefikFrontendRule: "Host:traefik.io", - label.TraefikFrontendWhitelistSourceRange: "10.10.10.10", - - label.TraefikFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.TraefikFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.TraefikFrontendSSLProxyHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.TraefikFrontendAllowedHosts: "foo,bar,bor", - label.TraefikFrontendHostsProxyHeaders: "foo,bar,bor", - label.TraefikFrontendSSLHost: "foo", - label.TraefikFrontendCustomFrameOptionsValue: "foo", - label.TraefikFrontendContentSecurityPolicy: "foo", - label.TraefikFrontendPublicKey: "foo", - label.TraefikFrontendReferrerPolicy: "foo", - label.TraefikFrontendSTSSeconds: "666", - label.TraefikFrontendSSLRedirect: "true", - label.TraefikFrontendSSLTemporaryRedirect: "true", - label.TraefikFrontendSTSIncludeSubdomains: "true", - label.TraefikFrontendSTSPreload: "true", - label.TraefikFrontendForceSTSHeader: "true", - label.TraefikFrontendFrameDeny: "true", - label.TraefikFrontendContentTypeNosniff: "true", - label.TraefikFrontendBrowserXSSFilter: "true", - label.TraefikFrontendIsDevelopment: "true", - }), - ports(nat.PortMap{ - "80/tcp": {}, - }), - withNetwork("bridge", ipv4("127.0.0.1")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-Host-traefik-io-0": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backend-foobar", - Routes: map[string]types.Route{ - "route-frontend-Host-traefik-io-0": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - PassTLSCert: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - WhitelistSourceRange: []string{ - "10.10.10.10", - }, - 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, - 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, - ContentSecurityPolicy: "foo", - PublicKey: "foo", - ReferrerPolicy: "foo", - IsDevelopment: true, - }, - Redirect: &types.Redirect{ - EntryPoint: "https", - Regex: "nope", - Replacement: "nope", - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-foobar": { - Servers: map[string]types.Server{ - "server-test1": { - URL: "https://127.0.0.1:666", - Weight: 12, - }, - }, - CircuitBreaker: &types.CircuitBreaker{ - Expression: "NetworkErrorRatio() > 0.5", - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - Sticky: true, - Stickiness: &types.Stickiness{ - CookieName: "chocolate", - }, - }, - MaxConn: &types.MaxConn{ - Amount: 666, - ExtractorFunc: "client.ip", - }, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - var dockerDataList []dockerData - for _, cont := range test.containers { - dData := parseContainer(cont) - dockerDataList = append(dockerDataList, dData) - } - - provider := &Provider{ - Domain: "docker.localhost", - ExposedByDefault: true, - } - actualConfig := provider.buildConfigurationV1(dockerDataList) - require.NotNil(t, actualConfig, "actualConfig") - - assert.EqualValues(t, test.expectedBackends, actualConfig.Backends) - assert.EqualValues(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestDockerTraefikFilterV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected bool - provider *Provider - }{ - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{}, - NetworkSettings: &docker.NetworkSettings{}, - }, - expected: false, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikEnable: "false", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: false, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container-multi-ports", - }, - Config: &container.Config{}, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - "443/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{}, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikPort: "80", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - "443/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikEnable: "true", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikEnable: "anything", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: true, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{}, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: false, - }, - expected: false, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikEnable: "true", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - Domain: "test", - ExposedByDefault: false, - }, - expected: true, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikEnable: "true", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - ExposedByDefault: false, - }, - expected: false, - }, - { - container: docker.ContainerJSON{ - ContainerJSONBase: &docker.ContainerJSONBase{ - Name: "container", - }, - Config: &container.Config{ - Labels: map[string]string{ - label.TraefikEnable: "true", - label.TraefikFrontendRule: "Host:i.love.this.host", - }, - }, - NetworkSettings: &docker.NetworkSettings{ - NetworkSettingsBase: docker.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80/tcp": {}, - }, - }, - }, - }, - provider: &Provider{ - ExposedByDefault: false, - }, - expected: true, - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := test.provider.containerFilterV1(dData) - if actual != test.expected { - t.Errorf("expected %v for %+v, got %+v", test.expected, test, actual) - } - }) - } -} - -func TestDockerGetFuncStringLabelV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - labelName string - defaultValue string - expected string - }{ - { - container: containerJSON(), - labelName: label.TraefikProtocol, - defaultValue: label.DefaultProtocol, - expected: "http", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikProtocol: "https", - })), - labelName: label.TraefikProtocol, - defaultValue: label.DefaultProtocol, - expected: "https", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(test.labelName+strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getFuncStringLabelV1(test.labelName, test.defaultValue)(dData) - if actual != test.expected { - t.Errorf("got %q, expected %q", actual, test.expected) - } - }) - } -} - -func TestDockerGetSliceStringLabelV1(t *testing.T) { - testCases := []struct { - desc string - container docker.ContainerJSON - labelName string - expected []string - }{ - { - desc: "no whitelist-label", - container: containerJSON(), - expected: nil, - }, - { - desc: "whitelist-label with empty string", - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendWhitelistSourceRange: "", - })), - labelName: label.TraefikFrontendWhitelistSourceRange, - expected: nil, - }, - { - desc: "whitelist-label with IPv4 mask", - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendWhitelistSourceRange: "1.2.3.4/16", - })), - labelName: label.TraefikFrontendWhitelistSourceRange, - expected: []string{ - "1.2.3.4/16", - }, - }, - { - desc: "whitelist-label with IPv6 mask", - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendWhitelistSourceRange: "fe80::/16", - })), - labelName: label.TraefikFrontendWhitelistSourceRange, - expected: []string{ - "fe80::/16", - }, - }, - { - desc: "whitelist-label with multiple masks", - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendWhitelistSourceRange: "1.1.1.1/24, 1234:abcd::42/32", - })), - labelName: label.TraefikFrontendWhitelistSourceRange, - expected: []string{ - "1.1.1.1/24", - "1234:abcd::42/32", - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getFuncSliceStringLabelV1(test.labelName)(dData) - if !reflect.DeepEqual(actual, test.expected) { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestDockerGetFrontendNameV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(name("foo")), - expected: "Host-foo-docker-localhost-0", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendRule: "Headers:User-Agent,bat/0.1.0", - })), - expected: "Headers-User-Agent-bat-0-1-0-0", - }, - { - container: containerJSON(labels(map[string]string{ - "com.docker.compose.project": "foo", - "com.docker.compose.service": "bar", - })), - expected: "Host-bar-foo-docker-localhost-0", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - })), - expected: "Host-foo-bar-0", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendRule: "Path:/test", - })), - expected: "Path-test-0", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendRule: "PathPrefix:/test2", - })), - expected: "PathPrefix-test2-0", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - provider := &Provider{ - Domain: "docker.localhost", - } - - actual := provider.getFrontendNameV1(dData, 0) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestDockerGetFrontendRuleV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(name("foo")), - expected: "Host:foo.docker.localhost", - }, - { - container: containerJSON(name("foo"), - labels(map[string]string{ - label.TraefikDomain: "traefik.localhost", - })), - expected: "Host:foo.traefik.localhost", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - })), - expected: "Host:foo.bar", - }, - { - container: containerJSON(labels(map[string]string{ - "com.docker.compose.project": "foo", - "com.docker.compose.service": "bar", - })), - expected: "Host:bar.foo.docker.localhost", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendRule: "Path:/test", - })), - expected: "Path:/test", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - provider := &Provider{ - Domain: "docker.localhost", - } - - actual := provider.getFrontendRuleV1(dData) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestDockerGetBackendNameV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(name("foo")), - expected: "foo", - }, - { - container: containerJSON(name("bar")), - expected: "bar", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikBackend: "foobar", - })), - expected: "foobar", - }, - { - container: containerJSON(labels(map[string]string{ - "com.docker.compose.project": "foo", - "com.docker.compose.service": "bar", - })), - expected: "bar-foo", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getBackendNameV1(dData) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestDockerGetIPAddressV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(withNetwork("testnet", ipv4("10.11.12.13"))), - expected: "10.11.12.13", - }, - { - container: containerJSON( - labels(map[string]string{ - labelDockerNetwork: "testnet", - }), - withNetwork("testnet", ipv4("10.11.12.13")), - ), - expected: "10.11.12.13", - }, - { - container: containerJSON( - labels(map[string]string{ - labelDockerNetwork: "testnet2", - }), - withNetwork("testnet", ipv4("10.11.12.13")), - withNetwork("testnet2", ipv4("10.11.12.14")), - ), - expected: "10.11.12.14", - }, - { - container: containerJSON( - networkMode("host"), - withNetwork("testnet", ipv4("10.11.12.13")), - withNetwork("testnet2", ipv4("10.11.12.14")), - ), - expected: "127.0.0.1", - }, - { - container: containerJSON( - networkMode("host"), - ), - expected: "127.0.0.1", - }, - { - container: containerJSON( - networkMode("host"), - nodeIP("10.0.0.5"), - ), - expected: "10.0.0.5", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - dData := parseContainer(test.container) - provider := &Provider{} - actual := provider.getDeprecatedIPAddress(dData) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestDockerGetPortV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(name("foo")), - expected: "", - }, - { - container: containerJSON(ports(nat.PortMap{ - "80/tcp": {}, - })), - expected: "80", - }, - { - container: containerJSON(ports(nat.PortMap{ - "80/tcp": {}, - "443/tcp": {}, - })), - expected: "80", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikPort: "8080", - })), - expected: "8080", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikPort: "8080", - }), ports(nat.PortMap{ - "80/tcp": {}, - })), - expected: "8080", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikPort: "8080", - }), ports(nat.PortMap{ - "8080/tcp": {}, - "80/tcp": {}, - })), - expected: "8080", - }, - } - - for containerID, e := range testCases { - e := e - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(e.container) - - actual := getPortV1(dData) - if actual != e.expected { - t.Errorf("expected %q, got %q", e.expected, actual) - } - }) - } -} diff --git a/provider/docker/deprecated_container_swarm_test.go b/provider/docker/deprecated_container_swarm_test.go deleted file mode 100644 index d53adf1ea..000000000 --- a/provider/docker/deprecated_container_swarm_test.go +++ /dev/null @@ -1,709 +0,0 @@ -package docker - -import ( - "strconv" - "testing" - - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - docker "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/swarm" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestSwarmBuildConfigurationV1(t *testing.T) { - testCases := []struct { - desc string - services []swarm.Service - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - networks map[string]*docker.NetworkResource - }{ - { - desc: "when no container", - services: []swarm.Service{}, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - networks: map[string]*docker.NetworkResource{}, - }, - { - desc: "when basic container configuration", - services: []swarm.Service{ - swarmService( - serviceName("test"), - serviceLabels(map[string]string{ - label.TraefikPort: "80", - }), - withEndpointSpec(modeVIP), - withEndpoint(virtualIP("1", "127.0.0.1/24")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-Host-test-docker-localhost-0": { - Backend: "backend-test", - PassHostHeader: true, - EntryPoints: []string{}, - BasicAuth: []string{}, - Routes: map[string]types.Route{ - "route-frontend-Host-test-docker-localhost-0": { - Rule: "Host:test.docker.localhost", - }, - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-test": { - Servers: map[string]types.Server{ - "server-test": { - URL: "http://127.0.0.1:80", - Weight: label.DefaultWeight, - }, - }, - }, - }, - networks: map[string]*docker.NetworkResource{ - "1": { - Name: "foo", - }, - }, - }, - { - desc: "when container has label 'enable' to false", - services: []swarm.Service{ - swarmService( - serviceName("test1"), - serviceLabels(map[string]string{ - label.TraefikEnable: "false", - label.TraefikPort: "666", - label.TraefikProtocol: "https", - label.TraefikWeight: "12", - label.TraefikBackend: "foobar", - }), - withEndpointSpec(modeVIP), - withEndpoint(virtualIP("1", "127.0.0.1/24")), - ), - }, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - networks: map[string]*docker.NetworkResource{ - "1": { - Name: "foo", - }, - }, - }, - { - desc: "when all labels are set", - services: []swarm.Service{ - swarmService( - serviceName("test1"), - serviceLabels(map[string]string{ - label.TraefikPort: "666", - label.TraefikProtocol: "https", - label.TraefikWeight: "12", - - label.TraefikBackend: "foobar", - - label.TraefikBackendCircuitBreakerExpression: "NetworkErrorRatio() > 0.5", - label.TraefikBackendLoadBalancerMethod: "drr", - label.TraefikBackendLoadBalancerSticky: "true", - label.TraefikBackendLoadBalancerStickiness: "true", - label.TraefikBackendLoadBalancerStickinessCookieName: "chocolate", - label.TraefikBackendMaxConnAmount: "666", - label.TraefikBackendMaxConnExtractorFunc: "client.ip", - - label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - label.TraefikFrontendEntryPoints: "http,https", - label.TraefikFrontendPassHostHeader: "true", - label.TraefikFrontendPassTLSCert: "true", - label.TraefikFrontendPriority: "666", - label.TraefikFrontendRedirectEntryPoint: "https", - label.TraefikFrontendRedirectRegex: "nope", - label.TraefikFrontendRedirectReplacement: "nope", - label.TraefikFrontendRule: "Host:traefik.io", - label.TraefikFrontendWhitelistSourceRange: "10.10.10.10", - - label.TraefikFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.TraefikFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.TraefikFrontendSSLProxyHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.TraefikFrontendAllowedHosts: "foo,bar,bor", - label.TraefikFrontendHostsProxyHeaders: "foo,bar,bor", - label.TraefikFrontendSSLHost: "foo", - label.TraefikFrontendCustomFrameOptionsValue: "foo", - label.TraefikFrontendContentSecurityPolicy: "foo", - label.TraefikFrontendPublicKey: "foo", - label.TraefikFrontendReferrerPolicy: "foo", - label.TraefikFrontendSTSSeconds: "666", - label.TraefikFrontendSSLRedirect: "true", - label.TraefikFrontendSSLTemporaryRedirect: "true", - label.TraefikFrontendSTSIncludeSubdomains: "true", - label.TraefikFrontendSTSPreload: "true", - label.TraefikFrontendForceSTSHeader: "true", - label.TraefikFrontendFrameDeny: "true", - label.TraefikFrontendContentTypeNosniff: "true", - label.TraefikFrontendBrowserXSSFilter: "true", - label.TraefikFrontendIsDevelopment: "true", - }), - withEndpointSpec(modeVIP), - withEndpoint(virtualIP("1", "127.0.0.1/24")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-Host-traefik-io-0": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backend-foobar", - Routes: map[string]types.Route{ - "route-frontend-Host-traefik-io-0": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - PassTLSCert: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - WhitelistSourceRange: []string{ - "10.10.10.10", - }, - 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, - 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, - ContentSecurityPolicy: "foo", - PublicKey: "foo", - ReferrerPolicy: "foo", - IsDevelopment: true, - }, - Redirect: &types.Redirect{ - EntryPoint: "https", - Regex: "nope", - Replacement: "nope", - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-foobar": { - Servers: map[string]types.Server{ - "server-test1": { - URL: "https://127.0.0.1:666", - Weight: 12, - }, - }, - CircuitBreaker: &types.CircuitBreaker{ - Expression: "NetworkErrorRatio() > 0.5", - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - Sticky: true, - Stickiness: &types.Stickiness{ - CookieName: "chocolate", - }, - }, - MaxConn: &types.MaxConn{ - Amount: 666, - ExtractorFunc: "client.ip", - }, - }, - }, - networks: map[string]*docker.NetworkResource{ - "1": { - Name: "foo", - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - var dockerDataList []dockerData - for _, service := range test.services { - dData := parseService(service, test.networks) - dockerDataList = append(dockerDataList, dData) - } - - provider := &Provider{ - Domain: "docker.localhost", - ExposedByDefault: true, - SwarmMode: true, - } - - actualConfig := provider.buildConfigurationV1(dockerDataList) - require.NotNil(t, actualConfig, "actualConfig") - - assert.EqualValues(t, test.expectedBackends, actualConfig.Backends) - assert.EqualValues(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestSwarmTraefikFilterV1(t *testing.T) { - testCases := []struct { - service swarm.Service - expected bool - networks map[string]*docker.NetworkResource - provider *Provider - }{ - { - service: swarmService(), - expected: false, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: true, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikEnable: "false", - label.TraefikPort: "80", - })), - expected: false, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: true, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - label.TraefikPort: "80", - })), - expected: true, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: true, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikPort: "80", - })), - expected: true, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: true, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikEnable: "true", - label.TraefikPort: "80", - })), - expected: true, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: true, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikEnable: "anything", - label.TraefikPort: "80", - })), - expected: true, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: true, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - label.TraefikPort: "80", - })), - expected: true, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: true, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikPort: "80", - })), - expected: false, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: false, - }, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikEnable: "true", - label.TraefikPort: "80", - })), - expected: true, - networks: map[string]*docker.NetworkResource{}, - provider: &Provider{ - SwarmMode: true, - Domain: "test", - ExposedByDefault: false, - }, - }, - } - - for serviceID, test := range testCases { - test := test - t.Run(strconv.Itoa(serviceID), func(t *testing.T) { - t.Parallel() - - dData := parseService(test.service, test.networks) - - actual := test.provider.containerFilterV1(dData) - if actual != test.expected { - t.Errorf("expected %v for %+v, got %+v", test.expected, test, actual) - } - }) - } -} - -func TestSwarmGetFuncStringLabelV1(t *testing.T) { - testCases := []struct { - service swarm.Service - labelName string - defaultValue string - networks map[string]*docker.NetworkResource - expected string - }{ - { - service: swarmService(), - labelName: label.TraefikProtocol, - defaultValue: label.DefaultProtocol, - networks: map[string]*docker.NetworkResource{}, - expected: "http", - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikProtocol: "https", - })), - labelName: label.TraefikProtocol, - defaultValue: label.DefaultProtocol, - networks: map[string]*docker.NetworkResource{}, - expected: "https", - }, - } - - for serviceID, test := range testCases { - test := test - t.Run(test.labelName+strconv.Itoa(serviceID), func(t *testing.T) { - t.Parallel() - - dData := parseService(test.service, test.networks) - - actual := getFuncStringLabelV1(test.labelName, test.defaultValue)(dData) - if actual != test.expected { - t.Errorf("got %q, expected %q", actual, test.expected) - } - }) - } -} - -func TestSwarmGetFrontendNameV1(t *testing.T) { - testCases := []struct { - service swarm.Service - expected string - networks map[string]*docker.NetworkResource - }{ - { - service: swarmService(serviceName("foo")), - expected: "Host-foo-docker-localhost-0", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikFrontendRule: "Headers:User-Agent,bat/0.1.0", - })), - expected: "Headers-User-Agent-bat-0-1-0-0", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - })), - expected: "Host-foo-bar-0", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikFrontendRule: "Path:/test", - })), - expected: "Path-test-0", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService( - serviceName("test"), - serviceLabels(map[string]string{ - label.TraefikFrontendRule: "PathPrefix:/test2", - }), - ), - expected: "PathPrefix-test2-0", - networks: map[string]*docker.NetworkResource{}, - }, - } - - for serviceID, test := range testCases { - test := test - t.Run(strconv.Itoa(serviceID), func(t *testing.T) { - t.Parallel() - - dData := parseService(test.service, test.networks) - - provider := &Provider{ - Domain: "docker.localhost", - SwarmMode: true, - } - - actual := provider.getFrontendNameV1(dData, 0) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestSwarmGetFrontendRuleV1(t *testing.T) { - testCases := []struct { - service swarm.Service - expected string - networks map[string]*docker.NetworkResource - }{ - { - service: swarmService(serviceName("foo")), - expected: "Host:foo.docker.localhost", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceName("foo"), - serviceLabels(map[string]string{ - label.TraefikDomain: "traefik.localhost", - })), - expected: "Host:foo.traefik.localhost", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - })), - expected: "Host:foo.bar", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikFrontendRule: "Path:/test", - })), - expected: "Path:/test", - networks: map[string]*docker.NetworkResource{}, - }, - } - - for serviceID, test := range testCases { - test := test - t.Run(strconv.Itoa(serviceID), func(t *testing.T) { - t.Parallel() - - dData := parseService(test.service, test.networks) - - provider := &Provider{ - Domain: "docker.localhost", - SwarmMode: true, - } - - actual := provider.getFrontendRuleV1(dData) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestSwarmGetBackendNameV1(t *testing.T) { - testCases := []struct { - service swarm.Service - expected string - networks map[string]*docker.NetworkResource - }{ - { - service: swarmService(serviceName("foo")), - expected: "foo", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceName("bar")), - expected: "bar", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService(serviceLabels(map[string]string{ - label.TraefikBackend: "foobar", - })), - expected: "foobar", - networks: map[string]*docker.NetworkResource{}, - }, - } - - for serviceID, test := range testCases { - test := test - t.Run(strconv.Itoa(serviceID), func(t *testing.T) { - t.Parallel() - - dData := parseService(test.service, test.networks) - - actual := getBackendNameV1(dData) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestSwarmGetIPAddressV1(t *testing.T) { - testCases := []struct { - service swarm.Service - expected string - networks map[string]*docker.NetworkResource - }{ - { - service: swarmService(withEndpointSpec(modeDNSSR)), - expected: "", - networks: map[string]*docker.NetworkResource{}, - }, - { - service: swarmService( - withEndpointSpec(modeVIP), - withEndpoint(virtualIP("1", "10.11.12.13/24")), - ), - expected: "10.11.12.13", - networks: map[string]*docker.NetworkResource{ - "1": { - Name: "foo", - }, - }, - }, - { - service: swarmService( - serviceLabels(map[string]string{ - labelDockerNetwork: "barnet", - }), - withEndpointSpec(modeVIP), - withEndpoint( - virtualIP("1", "10.11.12.13/24"), - virtualIP("2", "10.11.12.99/24"), - ), - ), - expected: "10.11.12.99", - networks: map[string]*docker.NetworkResource{ - "1": { - Name: "foonet", - }, - "2": { - Name: "barnet", - }, - }, - }, - } - - for serviceID, test := range testCases { - test := test - t.Run(strconv.Itoa(serviceID), func(t *testing.T) { - t.Parallel() - - dData := parseService(test.service, test.networks) - - provider := &Provider{ - SwarmMode: true, - } - - actual := provider.getDeprecatedIPAddress(dData) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestSwarmGetPortV1(t *testing.T) { - testCases := []struct { - service swarm.Service - expected string - networks map[string]*docker.NetworkResource - }{ - { - service: swarmService( - serviceLabels(map[string]string{ - label.TraefikPort: "8080", - }), - withEndpointSpec(modeDNSSR), - ), - expected: "8080", - networks: map[string]*docker.NetworkResource{}, - }, - } - - for serviceID, test := range testCases { - test := test - t.Run(strconv.Itoa(serviceID), func(t *testing.T) { - t.Parallel() - - dData := parseService(test.service, test.networks) - - actual := getPortV1(dData) - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} diff --git a/provider/docker/deprecated_service.go b/provider/docker/deprecated_service.go deleted file mode 100644 index a709cf0d5..000000000 --- a/provider/docker/deprecated_service.go +++ /dev/null @@ -1,197 +0,0 @@ -package docker - -import ( - "errors" - "strconv" - "strings" - - "github.com/containous/traefik/provider" - "github.com/containous/traefik/provider/label" -) - -// Specific functions - -// Extract rule from labels for a given service and a given docker container -// Deprecated -func (p Provider) getServiceFrontendRuleV1(container dockerData, serviceName string) string { - if value, ok := getServiceLabelsV1(container, serviceName)[label.SuffixFrontendRule]; ok { - return value - } - return p.getFrontendRuleV1(container) -} - -// Check if for the given container, we find labels that are defining services -// Deprecated -func hasServicesV1(container dockerData) bool { - return len(label.ExtractServiceProperties(container.Labels)) > 0 -} - -// Gets array of service names for a given container -// Deprecated -func getServiceNamesV1(container dockerData) []string { - labelServiceProperties := label.ExtractServiceProperties(container.Labels) - keys := make([]string, 0, len(labelServiceProperties)) - for k := range labelServiceProperties { - keys = append(keys, k) - } - return keys -} - -// checkServiceLabelPort checks if all service names have a port service label -// or if port container label exists for default value -// Deprecated -func checkServiceLabelPortV1(container dockerData) error { - // If port container label is present, there is a default values for all ports, use it for the check - _, err := strconv.Atoi(container.Labels[label.TraefikPort]) - if err != nil { - serviceLabelPorts := make(map[string]struct{}) - serviceLabels := make(map[string]struct{}) - for lbl := range container.Labels { - // Get all port service labels - portLabel := extractServicePortV1(lbl) - if len(portLabel) > 0 { - serviceLabelPorts[portLabel[0]] = struct{}{} - } - // Get only one instance of all service names from service labels - servicesLabelNames := label.FindSegmentSubmatch(lbl) - - if len(servicesLabelNames) > 0 { - serviceLabels[strings.Split(servicesLabelNames[0], ".")[1]] = struct{}{} - } - } - // If the number of service labels is different than the number of port services label - // there is an error - if len(serviceLabels) == len(serviceLabelPorts) { - for labelPort := range serviceLabelPorts { - _, err = strconv.Atoi(container.Labels[labelPort]) - if err != nil { - break - } - } - } else { - err = errors.New("port service labels missing, please use traefik.port as default value or define all port service labels") - } - } - return err -} - -// Deprecated -func extractServicePortV1(labelName string) []string { - if strings.HasPrefix(labelName, label.TraefikFrontend+".") || - strings.HasPrefix(labelName, label.TraefikBackend+".") { - return nil - } - - return label.PortRegexp.FindStringSubmatch(labelName) -} - -// Extract backend from labels for a given service and a given docker container -// Deprecated -func getServiceBackendNameV1(container dockerData, serviceName string) string { - if value, ok := getServiceLabelsV1(container, serviceName)[label.SuffixBackend]; ok { - return provider.Normalize(container.ServiceName + "-" + value) - } - return provider.Normalize(container.ServiceName + "-" + getBackendNameV1(container) + "-" + serviceName) -} - -// Extract port from labels for a given service and a given docker container -// Deprecated -func getServicePortV1(container dockerData, serviceName string) string { - if value, ok := getServiceLabelsV1(container, serviceName)[label.SuffixPort]; ok { - return value - } - return getPortV1(container) -} - -// Service label functions - -// Deprecated -func getFuncServiceSliceStringLabelV1(labelSuffix string) func(container dockerData, serviceName string) []string { - return func(container dockerData, serviceName string) []string { - serviceLabels := getServiceLabelsV1(container, serviceName) - return getServiceSliceValueV1(container, serviceLabels, labelSuffix) - } -} - -// Deprecated -func getFuncServiceStringLabelV1(labelSuffix string, defaultValue string) func(container dockerData, serviceName string) string { - return func(container dockerData, serviceName string) string { - serviceLabels := getServiceLabelsV1(container, serviceName) - return getServiceStringValueV1(container, serviceLabels, labelSuffix, defaultValue) - } -} - -// Deprecated -func getFuncServiceBoolLabelV1(labelSuffix string, defaultValue bool) func(container dockerData, serviceName string) bool { - return func(container dockerData, serviceName string) bool { - serviceLabels := getServiceLabelsV1(container, serviceName) - return getServiceBoolValueV1(container, serviceLabels, labelSuffix, defaultValue) - } -} - -// Deprecated -func getFuncServiceIntLabelV1(labelSuffix string, defaultValue int) func(container dockerData, serviceName string) int { - return func(container dockerData, serviceName string) int { - return getServiceIntLabelV1(container, serviceName, labelSuffix, defaultValue) - } -} - -// Deprecated -func getServiceStringValueV1(container dockerData, serviceLabels map[string]string, labelSuffix string, defaultValue string) string { - if value, ok := serviceLabels[labelSuffix]; ok { - return value - } - return label.GetStringValue(container.Labels, label.Prefix+labelSuffix, defaultValue) -} - -// Deprecated -func getServiceSliceValueV1(container dockerData, serviceLabels map[string]string, labelSuffix string) []string { - if value, ok := serviceLabels[labelSuffix]; ok { - return label.SplitAndTrimString(value, ",") - } - return label.GetSliceStringValue(container.Labels, label.Prefix+labelSuffix) -} - -// Deprecated -func getServiceBoolValueV1(container dockerData, serviceLabels map[string]string, labelSuffix string, defaultValue bool) bool { - if rawValue, ok := serviceLabels[labelSuffix]; ok { - value, err := strconv.ParseBool(rawValue) - if err == nil { - return value - } - } - return label.GetBoolValue(container.Labels, label.Prefix+labelSuffix, defaultValue) -} - -// Deprecated -func getServiceIntLabelV1(container dockerData, serviceName string, labelSuffix string, defaultValue int) int { - if rawValue, ok := getServiceLabelsV1(container, serviceName)[labelSuffix]; ok { - value, err := strconv.Atoi(rawValue) - if err == nil { - return value - } - } - return label.GetIntValue(container.Labels, label.Prefix+labelSuffix, defaultValue) -} - -// Deprecated -func getServiceLabelsV1(container dockerData, serviceName string) label.SegmentPropertyValues { - return label.ExtractServiceProperties(container.Labels)[serviceName] -} - -// Deprecated -func hasServiceRedirectV1(container dockerData, serviceName string) bool { - serviceLabels, ok := label.ExtractServiceProperties(container.Labels)[serviceName] - if !ok || len(serviceLabels) == 0 { - return false - } - - value, ok := serviceLabels[label.SuffixFrontendRedirectEntryPoint] - frep := ok && len(value) > 0 - value, ok = serviceLabels[label.SuffixFrontendRedirectRegex] - frrg := ok && len(value) > 0 - value, ok = serviceLabels[label.SuffixFrontendRedirectReplacement] - frrp := ok && len(value) > 0 - - return frep || frrg && frrp -} diff --git a/provider/docker/deprecated_service_test.go b/provider/docker/deprecated_service_test.go deleted file mode 100644 index 50c0a404c..000000000 --- a/provider/docker/deprecated_service_test.go +++ /dev/null @@ -1,695 +0,0 @@ -package docker - -import ( - "reflect" - "strconv" - "testing" - - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - docker "github.com/docker/docker/api/types" - "github.com/docker/go-connections/nat" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestDockerServiceBuildConfigurationV1(t *testing.T) { - testCases := []struct { - desc string - containers []docker.ContainerJSON - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - }{ - { - desc: "when no container", - containers: []docker.ContainerJSON{}, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - }, - { - desc: "simple configuration", - containers: []docker.ContainerJSON{ - containerJSON( - name("foo"), - labels(map[string]string{ - "traefik.service.port": "2503", - "traefik.service.frontend.entryPoints": "http,https", - }), - ports(nat.PortMap{ - "80/tcp": {}, - }), - withNetwork("bridge", ipv4("127.0.0.1")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-foo-foo-service": { - Backend: "backend-foo-foo-service", - PassHostHeader: true, - EntryPoints: []string{"http", "https"}, - BasicAuth: []string{}, - Routes: map[string]types.Route{ - "service-service": { - Rule: "Host:foo.docker.localhost", - }, - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-foo-foo-service": { - Servers: map[string]types.Server{ - "service-0": { - URL: "http://127.0.0.1:2503", - Weight: label.DefaultWeight, - }, - }, - CircuitBreaker: nil, - }, - }, - }, - { - desc: "when all labels are set", - containers: []docker.ContainerJSON{ - containerJSON( - name("foo"), - labels(map[string]string{ - label.Prefix + "service." + label.SuffixPort: "666", - label.Prefix + "service." + label.SuffixProtocol: "https", - label.Prefix + "service." + label.SuffixWeight: "12", - - label.Prefix + "service." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - label.Prefix + "service." + label.SuffixFrontendEntryPoints: "http,https", - label.Prefix + "service." + label.SuffixFrontendPassHostHeader: "true", - label.Prefix + "service." + label.SuffixFrontendPassTLSCert: "true", - label.Prefix + "service." + label.SuffixFrontendPriority: "666", - label.Prefix + "service." + label.SuffixFrontendRedirectEntryPoint: "https", - label.Prefix + "service." + label.SuffixFrontendRedirectRegex: "nope", - label.Prefix + "service." + label.SuffixFrontendRedirectReplacement: "nope", - label.Prefix + "service." + label.SuffixFrontendRedirectPermanent: "true", - label.Prefix + "service." + label.SuffixFrontendWhitelistSourceRange: "10.10.10.10", - - label.Prefix + "service." + label.SuffixFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.Prefix + "service." + label.SuffixFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.Prefix + "service." + label.SuffixFrontendHeadersSSLProxyHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", - label.Prefix + "service." + label.SuffixFrontendHeadersAllowedHosts: "foo,bar,bor", - label.Prefix + "service." + label.SuffixFrontendHeadersHostsProxyHeaders: "foo,bar,bor", - label.Prefix + "service." + label.SuffixFrontendHeadersSSLHost: "foo", - label.Prefix + "service." + label.SuffixFrontendHeadersCustomFrameOptionsValue: "foo", - label.Prefix + "service." + label.SuffixFrontendHeadersContentSecurityPolicy: "foo", - label.Prefix + "service." + label.SuffixFrontendHeadersPublicKey: "foo", - label.Prefix + "service." + label.SuffixFrontendHeadersReferrerPolicy: "foo", - label.Prefix + "service." + label.SuffixFrontendHeadersCustomBrowserXSSValue: "foo", - label.Prefix + "service." + label.SuffixFrontendHeadersSTSSeconds: "666", - label.Prefix + "service." + label.SuffixFrontendHeadersSSLRedirect: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersSSLTemporaryRedirect: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersSTSIncludeSubdomains: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersSTSPreload: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersForceSTSHeader: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersFrameDeny: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersContentTypeNosniff: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersBrowserXSSFilter: "true", - label.Prefix + "service." + label.SuffixFrontendHeadersIsDevelopment: "true", - }), - ports(nat.PortMap{ - "80/tcp": {}, - }), - withNetwork("bridge", ipv4("127.0.0.1")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-foo-foo-service": { - Backend: "backend-foo-foo-service", - EntryPoints: []string{ - "http", - "https", - }, - PassHostHeader: true, - PassTLSCert: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - Redirect: &types.Redirect{ - EntryPoint: "https", - Regex: "nope", - Replacement: "nope", - }, - Routes: map[string]types.Route{ - "service-service": { - Rule: "Host:foo.docker.localhost", - }, - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-foo-foo-service": { - Servers: map[string]types.Server{ - "service-0": { - URL: "https://127.0.0.1:666", - Weight: 12, - }, - }, - CircuitBreaker: nil, - }, - }, - }, - { - desc: "several containers", - containers: []docker.ContainerJSON{ - containerJSON( - name("test1"), - labels(map[string]string{ - "traefik.service.port": "2503", - "traefik.service.protocol": "https", - "traefik.service.weight": "80", - "traefik.service.backend": "foobar", - "traefik.service.frontend.passHostHeader": "false", - "traefik.service.frontend.rule": "Path:/mypath", - "traefik.service.frontend.priority": "5000", - "traefik.service.frontend.entryPoints": "http,https,ws", - "traefik.service.frontend.auth.basic": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - "traefik.service.frontend.redirect.entryPoint": "https", - }), - ports(nat.PortMap{ - "80/tcp": {}, - }), - withNetwork("bridge", ipv4("127.0.0.1")), - ), - containerJSON( - name("test2"), - labels(map[string]string{ - "traefik.anotherservice.port": "8079", - "traefik.anotherservice.weight": "33", - "traefik.anotherservice.frontend.rule": "Path:/anotherpath", - }), - ports(nat.PortMap{ - "80/tcp": {}, - }), - withNetwork("bridge", ipv4("127.0.0.1")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-test1-foobar": { - Backend: "backend-test1-foobar", - PassHostHeader: false, - Priority: 5000, - EntryPoints: []string{"http", "https", "ws"}, - BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, - Redirect: &types.Redirect{ - EntryPoint: "https", - }, - Routes: map[string]types.Route{ - "service-service": { - Rule: "Path:/mypath", - }, - }, - }, - "frontend-test2-test2-anotherservice": { - Backend: "backend-test2-test2-anotherservice", - PassHostHeader: true, - EntryPoints: []string{}, - BasicAuth: []string{}, - Routes: map[string]types.Route{ - "service-anotherservice": { - Rule: "Path:/anotherpath", - }, - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-test1-foobar": { - Servers: map[string]types.Server{ - "service-0": { - URL: "https://127.0.0.1:2503", - Weight: 80, - }, - }, - CircuitBreaker: nil, - }, - "backend-test2-test2-anotherservice": { - Servers: map[string]types.Server{ - "service-0": { - URL: "http://127.0.0.1:8079", - Weight: 33, - }, - }, - CircuitBreaker: nil, - }, - }, - }, - } - - provider := &Provider{ - Domain: "docker.localhost", - ExposedByDefault: true, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - var dockerDataList []dockerData - for _, container := range test.containers { - dData := parseContainer(container) - dockerDataList = append(dockerDataList, dData) - } - - actualConfig := provider.buildConfigurationV1(dockerDataList) - require.NotNil(t, actualConfig, "actualConfig") - - assert.EqualValues(t, test.expectedBackends, actualConfig.Backends) - assert.EqualValues(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestDockerGetFuncServiceStringLabelV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - suffixLabel string - defaultValue string - expected string - }{ - { - container: containerJSON(), - suffixLabel: label.SuffixProtocol, - defaultValue: label.DefaultProtocol, - expected: "http", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikProtocol: "https", - })), - suffixLabel: label.SuffixProtocol, - defaultValue: label.DefaultProtocol, - expected: "https", - }, - { - container: containerJSON(labels(map[string]string{ - label.Prefix + "myservice." + label.SuffixProtocol: "https", - })), - suffixLabel: label.SuffixProtocol, - defaultValue: label.DefaultProtocol, - expected: "https", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(test.suffixLabel+strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getFuncServiceStringLabelV1(test.suffixLabel, test.defaultValue)(dData, "myservice") - if actual != test.expected { - t.Errorf("got %q, expected %q", actual, test.expected) - } - }) - } -} - -func TestDockerGetFuncServiceSliceStringLabelV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - suffixLabel string - expected []string - }{ - { - container: containerJSON(), - suffixLabel: label.SuffixFrontendEntryPoints, - expected: nil, - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendEntryPoints: "http,https", - })), - suffixLabel: label.SuffixFrontendEntryPoints, - expected: []string{"http", "https"}, - }, - { - container: containerJSON(labels(map[string]string{ - "traefik.myservice.frontend.entryPoints": "http,https", - })), - suffixLabel: label.SuffixFrontendEntryPoints, - expected: []string{"http", "https"}, - }, - } - - for containerID, test := range testCases { - test := test - t.Run(test.suffixLabel+strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getFuncServiceSliceStringLabelV1(test.suffixLabel)(dData, "myservice") - - if !reflect.DeepEqual(actual, test.expected) { - t.Errorf("for container %q: got %q, expected %q", dData.Name, actual, test.expected) - } - }) - } -} - -func TestDockerGetServiceStringValueV1(t *testing.T) { - testCases := []struct { - desc string - container docker.ContainerJSON - serviceLabels map[string]string - labelSuffix string - defaultValue string - expected string - }{ - { - desc: "should use service label when label exists in service labels", - container: containerJSON( - name("test1"), - labels(map[string]string{ - "traefik.foo": "bir", - })), - serviceLabels: map[string]string{ - "foo": "bar", - }, - labelSuffix: "foo", - defaultValue: "fail", - expected: "bar", - }, - { - desc: "should use container label when label doesn't exist in service labels", - container: containerJSON( - name("test1"), - labels(map[string]string{ - "traefik.foo": "bir", - })), - serviceLabels: map[string]string{ - "fo": "bar", - }, - labelSuffix: "foo", - defaultValue: "fail", - expected: "bir", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getServiceStringValueV1(dData, test.serviceLabels, test.labelSuffix, test.defaultValue) - - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestDockerGetServiceSliceValueV1(t *testing.T) { - testCases := []struct { - desc string - container docker.ContainerJSON - serviceLabels map[string]string - labelSuffix string - expected []string - }{ - { - desc: "should return nil when no label", - container: containerJSON( - name("test1"), - labels(map[string]string{})), - serviceLabels: map[string]string{}, - expected: nil, - }, - { - desc: "should return a slice when label", - container: containerJSON( - name("test1"), - labels(map[string]string{ - "traefik.foo": "bor, byr, ber", - })), - serviceLabels: map[string]string{ - "foo": "bar, bir, bur", - }, - labelSuffix: "foo", - expected: []string{"bar", "bir", "bur"}, - }, - { - desc: "should return a slice when label (fallback to container labels)", - container: containerJSON( - name("test1"), - labels(map[string]string{ - "traefik.foo": "bor, byr, ber", - })), - serviceLabels: map[string]string{ - "fo": "bar, bir, bur", - }, - labelSuffix: "foo", - expected: []string{"bor", "byr", "ber"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getServiceSliceValueV1(dData, test.serviceLabels, test.labelSuffix) - - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestDockerGetServiceBoolValueV1(t *testing.T) { - testCases := []struct { - desc string - container docker.ContainerJSON - serviceLabels map[string]string - labelSuffix string - defaultValue bool - expected bool - }{ - { - desc: "should return default value when no label", - container: containerJSON( - name("test1"), - labels(map[string]string{})), - serviceLabels: map[string]string{}, - labelSuffix: "foo", - defaultValue: true, - expected: true, - }, - { - desc: "should return a bool when label", - container: containerJSON( - name("test1"), - labels(map[string]string{ - "traefik.foo": "false", - })), - serviceLabels: map[string]string{ - "foo": "true", - }, - labelSuffix: "foo", - expected: true, - }, - { - desc: "should return a bool when label (fallback to container labels)", - container: containerJSON( - name("test1"), - labels(map[string]string{ - "traefik.foo": "true", - })), - serviceLabels: map[string]string{ - "fo": "false", - }, - labelSuffix: "foo", - expected: true, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - - actual := getServiceBoolValueV1(dData, test.serviceLabels, test.labelSuffix, test.defaultValue) - - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestDockerCheckPortLabelsV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expectedError bool - }{ - { - container: containerJSON(labels(map[string]string{ - label.TraefikPort: "80", - })), - expectedError: false, - }, - { - container: containerJSON(labels(map[string]string{ - label.Prefix + "servicename.protocol": "http", - label.Prefix + "servicename.port": "80", - })), - expectedError: false, - }, - { - container: containerJSON(labels(map[string]string{ - label.Prefix + "servicename.protocol": "http", - label.TraefikPort: "80", - })), - expectedError: false, - }, - { - container: containerJSON(labels(map[string]string{ - label.Prefix + "servicename.protocol": "http", - })), - expectedError: true, - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - - dData := parseContainer(test.container) - err := checkServiceLabelPortV1(dData) - - if test.expectedError && err == nil { - t.Error("expected an error but got nil") - } else if !test.expectedError && err != nil { - t.Errorf("expected no error, got %q", err) - } - }) - } -} - -func TestDockerGetServiceBackendNameV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(name("foo")), - expected: "foo-foo-myservice", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikBackend: "another-backend", - })), - expected: "fake-another-backend-myservice", - }, - { - container: containerJSON(name("foo.bar")), - expected: "foo-bar-foo-bar-myservice", - }, - { - container: containerJSON(labels(map[string]string{ - "traefik.myservice.backend": "custom-backend", - })), - expected: "fake-custom-backend", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikBackend: "another.backend", - })), - expected: "fake-another-backend-myservice", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - dData := parseContainer(test.container) - actual := getServiceBackendNameV1(dData, "myservice") - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestDockerGetServiceFrontendRuleV1(t *testing.T) { - provider := &Provider{} - - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(name("foo")), - expected: "", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikFrontendRule: "Path:/helloworld", - })), - expected: "Path:/helloworld", - }, - { - container: containerJSON(labels(map[string]string{ - "traefik.myservice.frontend.rule": "Path:/mycustomservicepath", - })), - expected: "Path:/mycustomservicepath", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - dData := parseContainer(test.container) - actual := provider.getServiceFrontendRuleV1(dData, "myservice") - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} - -func TestDockerGetServicePortV1(t *testing.T) { - testCases := []struct { - container docker.ContainerJSON - expected string - }{ - { - container: containerJSON(), - expected: "", - }, - { - container: containerJSON(labels(map[string]string{ - label.TraefikPort: "2500", - })), - expected: "2500", - }, - { - container: containerJSON(labels(map[string]string{ - "traefik.myservice.port": "1234", - })), - expected: "1234", - }, - } - - for containerID, test := range testCases { - test := test - t.Run(strconv.Itoa(containerID), func(t *testing.T) { - t.Parallel() - dData := parseContainer(test.container) - actual := getServicePortV1(dData, "myservice") - if actual != test.expected { - t.Errorf("expected %q, got %q", test.expected, actual) - } - }) - } -} diff --git a/provider/ecs/config.go b/provider/ecs/config.go index 09dd8c2a9..00a497140 100644 --- a/provider/ecs/config.go +++ b/provider/ecs/config.go @@ -16,7 +16,7 @@ import ( ) // buildConfiguration fills the config template with the given instances -func (p *Provider) buildConfigurationV2(instances []ecsInstance) (*types.Configuration, error) { +func (p *Provider) buildConfiguration(instances []ecsInstance) (*types.Configuration, error) { services := make(map[string][]ecsInstance) for _, instance := range instances { backendName := getBackendName(instance) diff --git a/provider/ecs/config_root.go b/provider/ecs/config_root.go deleted file mode 100644 index 622edfcfc..000000000 --- a/provider/ecs/config_root.go +++ /dev/null @@ -1,12 +0,0 @@ -package ecs - -import ( - "github.com/containous/traefik/types" -) - -func (p *Provider) buildConfiguration(instances []ecsInstance) (*types.Configuration, error) { - if p.TemplateVersion == 1 { - return p.buildConfigurationV1(instances) - } - return p.buildConfigurationV2(instances) -} diff --git a/provider/ecs/config_test.go b/provider/ecs/config_test.go index 2e0b620c7..5f6f41f9b 100644 --- a/provider/ecs/config_test.go +++ b/provider/ecs/config_test.go @@ -1144,82 +1144,6 @@ func TestGetPort(t *testing.T) { } } -func TestGetFuncStringValue(t *testing.T) { - testCases := []struct { - desc string - expected string - instanceInfo ecsInstance - }{ - { - desc: "Protocol label is not set should return a string equals to http", - expected: "http", - instanceInfo: simpleEcsInstance(map[string]*string{}), - }, - { - desc: "Protocol label is set to http should return a string equals to http", - expected: "http", - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikProtocol: aws.String("http"), - }), - }, - { - desc: "Protocol label is set to https should return a string equals to https", - expected: "https", - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikProtocol: aws.String("https"), - }), - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := getFuncStringValueV1(label.TraefikProtocol, label.DefaultProtocol)(test.instanceInfo) - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestGetFuncSliceString(t *testing.T) { - testCases := []struct { - desc string - expected []string - instanceInfo ecsInstance - }{ - { - desc: "Frontend entrypoints label not set should return empty array", - expected: nil, - instanceInfo: simpleEcsInstance(map[string]*string{}), - }, - { - desc: "Frontend entrypoints label set to http should return a string array of 1 element", - expected: []string{"http"}, - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikFrontendEntryPoints: aws.String("http"), - }), - }, - { - desc: "Frontend entrypoints label set to http,https should return a string array of 2 elements", - expected: []string{"http", "https"}, - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikFrontendEntryPoints: aws.String("http,https"), - }), - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := getFuncSliceStringV1(label.TraefikFrontendEntryPoints)(test.instanceInfo) - assert.Equal(t, test.expected, actual) - }) - } -} - func makeEcsInstance(containerDef *ecs.ContainerDefinition) ecsInstance { container := &ecs.Container{ Name: containerDef.Name, diff --git a/provider/ecs/deprecated_config.go b/provider/ecs/deprecated_config.go deleted file mode 100644 index 06808b7f1..000000000 --- a/provider/ecs/deprecated_config.go +++ /dev/null @@ -1,260 +0,0 @@ -package ecs - -import ( - "strconv" - "strings" - "text/template" - - "github.com/BurntSushi/ty/fun" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ec2" - "github.com/containous/traefik/log" - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" -) - -// buildConfiguration fills the config template with the given instances -// Deprecated -func (p *Provider) buildConfigurationV1(instances []ecsInstance) (*types.Configuration, error) { - services := make(map[string][]ecsInstance) - for _, instance := range instances { - backendName := getBackendNameV1(instance) - if p.filterInstanceV1(instance) { - if serviceInstances, ok := services[backendName]; ok { - services[backendName] = append(serviceInstances, instance) - } else { - services[backendName] = []ecsInstance{instance} - } - } - } - - var ecsFuncMap = template.FuncMap{ - // Backend functions - "getHost": getHost, - "getPort": getPort, - - "getProtocol": getFuncStringValueV1(label.TraefikProtocol, label.DefaultProtocol), - "getWeight": getFuncIntValueV1(label.TraefikWeight, label.DefaultWeight), - "getLoadBalancerMethod": getFuncFirstStringValueV1(label.TraefikBackendLoadBalancerMethod, label.DefaultBackendLoadBalancerMethod), - "getLoadBalancerSticky": getStickyV1, - "hasStickinessLabel": getFuncFirstBoolValueV1(label.TraefikBackendLoadBalancerStickiness, false), - "getStickinessCookieName": getFuncFirstStringValueV1(label.TraefikBackendLoadBalancerStickinessCookieName, label.DefaultBackendLoadbalancerStickinessCookieName), - "hasHealthCheckLabels": hasFuncFirstV1(label.TraefikBackendHealthCheckPath), - "getHealthCheckPath": getFuncFirstStringValueV1(label.TraefikBackendHealthCheckPath, ""), - "getHealthCheckInterval": getFuncFirstStringValueV1(label.TraefikBackendHealthCheckInterval, ""), - - // Frontend functions - "filterFrontends": filterFrontendsV1, - "getFrontendRule": p.getFrontendRule, - "getPassHostHeader": getFuncBoolValueV1(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), - "getPassTLSCert": getFuncBoolValueV1(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), - "getPriority": getFuncIntValueV1(label.TraefikFrontendPriority, label.DefaultFrontendPriority), - "getBasicAuth": getFuncSliceStringV1(label.TraefikFrontendAuthBasic), - "getEntryPoints": getFuncSliceStringV1(label.TraefikFrontendEntryPoints), - } - - return p.GetConfiguration("templates/ecs-v1.tmpl", ecsFuncMap, struct { - Services map[string][]ecsInstance - }{ - Services: services, - }) -} - -// Deprecated -func getBackendNameV1(i ecsInstance) string { - return getStringValueV1(i, label.TraefikBackend, i.Name) -} - -// Deprecated -func filterFrontendsV1(instances []ecsInstance) []ecsInstance { - byName := make(map[string]struct{}) - - return fun.Filter(func(i ecsInstance) bool { - backendName := getBackendName(i) - _, found := byName[backendName] - if !found { - byName[backendName] = struct{}{} - } - return !found - }, instances).([]ecsInstance) -} - -// Deprecated -func (p *Provider) filterInstanceV1(i ecsInstance) bool { - if i.machine == nil { - log.Debug("Filtering ecs instance with nil machine") - return false - } - - if labelPort := getStringValueV1(i, label.TraefikPort, ""); len(i.machine.ports) == 0 && labelPort == "" { - log.Debugf("Filtering ecs instance without port %s (%s)", i.Name, i.ID) - return false - } - - if strings.ToLower(i.machine.state) != ec2.InstanceStateNameRunning { - log.Debugf("Filtering ecs instance in an incorrect state %s (%s) (state = %s)", i.Name, i.ID, i.machine.state) - return false - } - - if len(i.machine.privateIP) == 0 { - log.Debugf("Filtering ecs instance without an ip address %s (%s)", i.Name, i.ID) - return false - } - - if !isEnabled(i, p.ExposedByDefault) { - log.Debugf("Filtering disabled ecs instance %s (%s)", i.Name, i.ID) - return false - } - - return true -} - -// TODO: Deprecated -// replaced by Stickiness -// Deprecated -func getStickyV1(instances []ecsInstance) bool { - if hasFirstV1(instances, label.TraefikBackendLoadBalancerSticky) { - log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness) - } - return getFirstBoolValueV1(instances, label.TraefikBackendLoadBalancerSticky, false) -} - -// Label functions - -// Deprecated -func getFuncStringValueV1(labelName string, defaultValue string) func(i ecsInstance) string { - return func(i ecsInstance) string { - return getStringValueV1(i, labelName, defaultValue) - } -} - -// Deprecated -func getFuncBoolValueV1(labelName string, defaultValue bool) func(i ecsInstance) bool { - return func(i ecsInstance) bool { - return getBoolValueV1(i, labelName, defaultValue) - } -} - -// Deprecated -func getFuncIntValueV1(labelName string, defaultValue int) func(i ecsInstance) int { - return func(i ecsInstance) int { - return getIntValueV1(i, labelName, defaultValue) - } -} - -// Deprecated -func getFuncSliceStringV1(labelName string) func(i ecsInstance) []string { - return func(i ecsInstance) []string { - return getSliceStringV1(i, labelName) - } -} - -// Deprecated -func hasLabelV1(i ecsInstance, labelName string) bool { - value, ok := i.containerDefinition.DockerLabels[labelName] - return ok && value != nil && len(aws.StringValue(value)) > 0 -} - -// Deprecated -func getStringValueV1(i ecsInstance, labelName string, defaultValue string) string { - if v, ok := i.containerDefinition.DockerLabels[labelName]; ok { - if v == nil { - return defaultValue - } - if len(aws.StringValue(v)) == 0 { - return defaultValue - } - return aws.StringValue(v) - } - return defaultValue -} - -// Deprecated -func getBoolValueV1(i ecsInstance, labelName string, defaultValue bool) bool { - rawValue, ok := i.containerDefinition.DockerLabels[labelName] - if ok { - if rawValue != nil { - v, err := strconv.ParseBool(aws.StringValue(rawValue)) - if err == nil { - return v - } - } - } - return defaultValue -} - -// Deprecated -func getIntValueV1(i ecsInstance, labelName string, defaultValue int) int { - rawValue, ok := i.containerDefinition.DockerLabels[labelName] - if ok { - if rawValue != nil { - v, err := strconv.Atoi(aws.StringValue(rawValue)) - if err == nil { - return v - } - } - } - return defaultValue -} - -// Deprecated -func getSliceStringV1(i ecsInstance, labelName string) []string { - if value, ok := i.containerDefinition.DockerLabels[labelName]; ok { - if value == nil { - return nil - } - if len(aws.StringValue(value)) == 0 { - return nil - } - return label.SplitAndTrimString(aws.StringValue(value), ",") - } - return nil -} - -// Deprecated -func hasFuncFirstV1(labelName string) func(instances []ecsInstance) bool { - return func(instances []ecsInstance) bool { - return hasFirstV1(instances, labelName) - } -} - -// Deprecated -func getFuncFirstStringValueV1(labelName string, defaultValue string) func(instances []ecsInstance) string { - return func(instances []ecsInstance) string { - return getFirstStringValueV1(instances, labelName, defaultValue) - } -} - -// Deprecated -func getFuncFirstBoolValueV1(labelName string, defaultValue bool) func(instances []ecsInstance) bool { - return func(instances []ecsInstance) bool { - if len(instances) == 0 { - return defaultValue - } - return getBoolValueV1(instances[0], labelName, defaultValue) - } -} - -// Deprecated -func hasFirstV1(instances []ecsInstance, labelName string) bool { - if len(instances) == 0 { - return false - } - return hasLabelV1(instances[0], labelName) -} - -// Deprecated -func getFirstStringValueV1(instances []ecsInstance, labelName string, defaultValue string) string { - if len(instances) == 0 { - return defaultValue - } - return getStringValueV1(instances[0], labelName, defaultValue) -} - -// Deprecated -func getFirstBoolValueV1(instances []ecsInstance, labelName string, defaultValue bool) bool { - if len(instances) == 0 { - return defaultValue - } - return getBoolValueV1(instances[0], labelName, defaultValue) -} diff --git a/provider/ecs/deprecated_config_test.go b/provider/ecs/deprecated_config_test.go deleted file mode 100644 index aa0ad933a..000000000 --- a/provider/ecs/deprecated_config_test.go +++ /dev/null @@ -1,395 +0,0 @@ -package ecs - -import ( - "testing" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ec2" - "github.com/aws/aws-sdk-go/service/ecs" - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/stretchr/testify/assert" -) - -func TestBuildConfigurationV1(t *testing.T) { - testCases := []struct { - desc string - instances []ecsInstance - expected *types.Configuration - err error - }{ - { - desc: "config parsed successfully", - instances: []ecsInstance{ - { - Name: "testing", - ID: "1", - containerDefinition: &ecs.ContainerDefinition{ - DockerLabels: map[string]*string{}, - }, - machine: &machine{ - state: ec2.InstanceStateNameRunning, - privateIP: "10.0.0.1", - ports: []portMapping{{hostPort: 1337}}, - }, - }, - }, - expected: &types.Configuration{ - Backends: map[string]*types.Backend{ - "backend-testing": { - Servers: map[string]types.Server{ - "server-testing1": { - URL: "http://10.0.0.1:1337", - Weight: label.DefaultWeight, - }}, - LoadBalancer: &types.LoadBalancer{ - Method: "wrr", - }, - }, - }, - Frontends: map[string]*types.Frontend{ - "frontend-testing": { - EntryPoints: []string{}, - Backend: "backend-testing", - Routes: map[string]types.Route{ - "route-frontend-testing": { - Rule: "Host:testing.", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - }, - }, - }, - }, - { - desc: "config parsed successfully with health check labels", - instances: []ecsInstance{ - { - Name: "testing", - ID: "1", - containerDefinition: &ecs.ContainerDefinition{ - DockerLabels: map[string]*string{ - label.TraefikBackendHealthCheckPath: aws.String("/health"), - label.TraefikBackendHealthCheckInterval: aws.String("1s"), - }}, - machine: &machine{ - state: ec2.InstanceStateNameRunning, - privateIP: "10.0.0.1", - ports: []portMapping{{hostPort: 1337}}, - }, - }, - }, - expected: &types.Configuration{ - Backends: map[string]*types.Backend{ - "backend-testing": { - HealthCheck: &types.HealthCheck{ - Path: "/health", - Interval: "1s", - }, - Servers: map[string]types.Server{ - "server-testing1": { - URL: "http://10.0.0.1:1337", - Weight: label.DefaultWeight, - }}, - LoadBalancer: &types.LoadBalancer{ - Method: "wrr", - }, - }, - }, - Frontends: map[string]*types.Frontend{ - "frontend-testing": { - EntryPoints: []string{}, - Backend: "backend-testing", - Routes: map[string]types.Route{ - "route-frontend-testing": { - Rule: "Host:testing.", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - }, - }, - }, - }, - { - desc: "when all labels are set", - instances: []ecsInstance{ - { - Name: "testing-instance", - ID: "6", - containerDefinition: &ecs.ContainerDefinition{ - DockerLabels: map[string]*string{ - label.TraefikPort: aws.String("666"), - label.TraefikProtocol: aws.String("https"), - label.TraefikWeight: aws.String("12"), - - label.TraefikBackend: aws.String("foobar"), - - label.TraefikBackendHealthCheckPath: aws.String("/health"), - label.TraefikBackendHealthCheckInterval: aws.String("6"), - label.TraefikBackendLoadBalancerMethod: aws.String("drr"), - label.TraefikBackendLoadBalancerSticky: aws.String("true"), - label.TraefikBackendLoadBalancerStickiness: aws.String("true"), - label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"), - - label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - label.TraefikFrontendEntryPoints: aws.String("http,https"), - label.TraefikFrontendPassHostHeader: aws.String("true"), - label.TraefikFrontendPriority: aws.String("666"), - label.TraefikFrontendRule: aws.String("Host:traefik.io"), - }}, - machine: &machine{ - state: ec2.InstanceStateNameRunning, - privateIP: "10.0.0.1", - ports: []portMapping{{hostPort: 1337}}, - }, - }, - }, - expected: &types.Configuration{ - Backends: map[string]*types.Backend{ - "backend-foobar": { - Servers: map[string]types.Server{ - "server-testing-instance6": { - URL: "https://10.0.0.1:666", - Weight: 12, - }, - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - Sticky: true, - Stickiness: &types.Stickiness{ - CookieName: "chocolate", - }, - }, - HealthCheck: &types.HealthCheck{ - Path: "/health", - Interval: "6", - }, - }, - }, - Frontends: map[string]*types.Frontend{ - "frontend-foobar": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backend-foobar", - Routes: map[string]types.Route{ - "route-frontend-foobar": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - }, - }, { - desc: "Containers with same backend name", - instances: []ecsInstance{ - { - Name: "testing-instance", - ID: "6", - containerDefinition: &ecs.ContainerDefinition{ - DockerLabels: map[string]*string{ - label.TraefikPort: aws.String("666"), - label.TraefikProtocol: aws.String("https"), - label.TraefikWeight: aws.String("12"), - - label.TraefikBackend: aws.String("foobar"), - - label.TraefikBackendHealthCheckPath: aws.String("/health"), - label.TraefikBackendHealthCheckInterval: aws.String("6"), - label.TraefikBackendLoadBalancerMethod: aws.String("drr"), - label.TraefikBackendLoadBalancerSticky: aws.String("true"), - label.TraefikBackendLoadBalancerStickiness: aws.String("true"), - label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"), - - label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - label.TraefikFrontendEntryPoints: aws.String("http,https"), - label.TraefikFrontendPassHostHeader: aws.String("true"), - label.TraefikFrontendPriority: aws.String("666"), - label.TraefikFrontendRule: aws.String("Host:traefik.io"), - }}, - machine: &machine{ - state: ec2.InstanceStateNameRunning, - privateIP: "10.0.0.1", - ports: []portMapping{{hostPort: 1337}}, - }, - }, { - Name: "testing-instance-v2", - ID: "6", - containerDefinition: &ecs.ContainerDefinition{ - DockerLabels: map[string]*string{ - label.TraefikPort: aws.String("555"), - label.TraefikProtocol: aws.String("https"), - label.TraefikWeight: aws.String("12"), - - label.TraefikBackend: aws.String("foobar"), - - label.TraefikBackendHealthCheckPath: aws.String("/health"), - label.TraefikBackendHealthCheckInterval: aws.String("6"), - label.TraefikBackendLoadBalancerMethod: aws.String("drr"), - label.TraefikBackendLoadBalancerSticky: aws.String("true"), - label.TraefikBackendLoadBalancerStickiness: aws.String("true"), - label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"), - - label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - label.TraefikFrontendEntryPoints: aws.String("http,https"), - label.TraefikFrontendPassHostHeader: aws.String("true"), - label.TraefikFrontendPriority: aws.String("666"), - label.TraefikFrontendRule: aws.String("Host:traefik.io"), - }}, - machine: &machine{ - state: ec2.InstanceStateNameRunning, - privateIP: "10.0.0.2", - ports: []portMapping{{hostPort: 1337}}, - }, - }, - }, - expected: &types.Configuration{ - Backends: map[string]*types.Backend{ - "backend-foobar": { - Servers: map[string]types.Server{ - "server-testing-instance6": { - URL: "https://10.0.0.1:666", - Weight: 12, - }, - "server-testing-instance-v26": { - URL: "https://10.0.0.2:555", - Weight: 12, - }, - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - Sticky: true, - Stickiness: &types.Stickiness{ - CookieName: "chocolate", - }, - }, - HealthCheck: &types.HealthCheck{ - Path: "/health", - Interval: "6", - }, - }, - }, - Frontends: map[string]*types.Frontend{ - "frontend-foobar": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backend-foobar", - Routes: map[string]types.Route{ - "route-frontend-foobar": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - provider := &Provider{ExposedByDefault: true} - - instances := fakeLoadTraefikLabels(test.instances) - - got, err := provider.buildConfigurationV1(instances) - assert.Equal(t, test.err, err) // , err.Error() - assert.Equal(t, test.expected, got, test.desc) - }) - } -} - -func TestGetFuncStringValueV1(t *testing.T) { - testCases := []struct { - desc string - expected string - instanceInfo ecsInstance - }{ - { - desc: "Protocol label is not set should return a string equals to http", - expected: "http", - instanceInfo: simpleEcsInstance(map[string]*string{}), - }, - { - desc: "Protocol label is set to http should return a string equals to http", - expected: "http", - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikProtocol: aws.String("http"), - }), - }, - { - desc: "Protocol label is set to https should return a string equals to https", - expected: "https", - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikProtocol: aws.String("https"), - }), - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := getFuncStringValueV1(label.TraefikProtocol, label.DefaultProtocol)(test.instanceInfo) - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestGetFuncSliceStringV1(t *testing.T) { - testCases := []struct { - desc string - expected []string - instanceInfo ecsInstance - }{ - { - desc: "Frontend entrypoints label not set should return empty array", - expected: nil, - instanceInfo: simpleEcsInstance(map[string]*string{}), - }, - { - desc: "Frontend entrypoints label set to http should return a string array of 1 element", - expected: []string{"http"}, - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikFrontendEntryPoints: aws.String("http"), - }), - }, - { - desc: "Frontend entrypoints label set to http,https should return a string array of 2 elements", - expected: []string{"http", "https"}, - instanceInfo: simpleEcsInstance(map[string]*string{ - label.TraefikFrontendEntryPoints: aws.String("http,https"), - }), - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := getFuncSliceStringV1(label.TraefikFrontendEntryPoints)(test.instanceInfo) - assert.Equal(t, test.expected, actual) - }) - } -} diff --git a/provider/marathon/config.go b/provider/marathon/config.go index 8b0f61af9..2bf884755 100644 --- a/provider/marathon/config.go +++ b/provider/marathon/config.go @@ -25,7 +25,7 @@ type appData struct { LinkedApps []*appData } -func (p *Provider) buildConfigurationV2(applications *marathon.Applications) *types.Configuration { +func (p *Provider) buildConfiguration(applications *marathon.Applications) *types.Configuration { var MarathonFuncMap = template.FuncMap{ "getDomain": label.GetFuncString(label.TraefikDomain, p.Domain), // see https://github.com/containous/traefik/pull/1693 "getSubDomain": p.getSubDomain, // see https://github.com/containous/traefik/pull/1693 diff --git a/provider/marathon/config_root.go b/provider/marathon/config_root.go deleted file mode 100644 index 7a5b66e89..000000000 --- a/provider/marathon/config_root.go +++ /dev/null @@ -1,13 +0,0 @@ -package marathon - -import ( - "github.com/containous/traefik/types" - "github.com/gambol99/go-marathon" -) - -func (p *Provider) buildConfiguration(applications *marathon.Applications) *types.Configuration { - if p.TemplateVersion == 1 { - return p.buildConfigurationV1(applications) - } - return p.buildConfigurationV2(applications) -} diff --git a/provider/marathon/config_test.go b/provider/marathon/config_test.go index f6a5d3c9a..3dd1b690c 100644 --- a/provider/marathon/config_test.go +++ b/provider/marathon/config_test.go @@ -655,7 +655,7 @@ func TestBuildConfiguration(t *testing.T) { ExposedByDefault: true, } - actualConfig := p.buildConfigurationV2(test.applications) + actualConfig := p.buildConfiguration(test.applications) assert.NotNil(t, actualConfig) assert.Equal(t, test.expectedBackends, actualConfig.Backends) @@ -988,7 +988,7 @@ func TestBuildConfigurationSegments(t *testing.T) { ExposedByDefault: true, } - actualConfig := p.buildConfigurationV2(test.applications) + actualConfig := p.buildConfiguration(test.applications) assert.NotNil(t, actualConfig) assert.Equal(t, test.expectedBackends, actualConfig.Backends) diff --git a/provider/marathon/deprecated_config.go b/provider/marathon/deprecated_config.go deleted file mode 100644 index 69fba3e6f..000000000 --- a/provider/marathon/deprecated_config.go +++ /dev/null @@ -1,436 +0,0 @@ -package marathon - -import ( - "errors" - "fmt" - "math" - "strconv" - "strings" - "text/template" - - "github.com/BurntSushi/ty/fun" - "github.com/containous/traefik/log" - "github.com/containous/traefik/provider" - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/gambol99/go-marathon" -) - -func (p *Provider) buildConfigurationV1(applications *marathon.Applications) *types.Configuration { - var MarathonFuncMap = template.FuncMap{ - "getBackend": p.getBackendNameV1, - "getDomain": getFuncStringServiceV1(label.SuffixDomain, p.Domain), // see https://github.com/containous/traefik/pull/1693 - "getSubDomain": p.getSubDomain, // see https://github.com/containous/traefik/pull/1693 - - // Backend functions - "getBackendServer": p.getBackendServerV1, - "getPort": getPortV1, - "getServers": p.getServersV1, - - "getWeight": getFuncIntServiceV1(label.SuffixWeight, label.DefaultWeight), - "getProtocol": getFuncStringServiceV1(label.SuffixProtocol, label.DefaultProtocol), - "hasCircuitBreakerLabels": hasFuncV1(label.TraefikBackendCircuitBreakerExpression), - "getCircuitBreakerExpression": getFuncStringV1(label.TraefikBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression), - "hasLoadBalancerLabels": hasLoadBalancerLabelsV1, - "getLoadBalancerMethod": getFuncStringV1(label.TraefikBackendLoadBalancerMethod, label.DefaultBackendLoadBalancerMethod), - "getSticky": getStickyV1, - "hasStickinessLabel": hasFuncV1(label.TraefikBackendLoadBalancerStickiness), - "getStickinessCookieName": getFuncStringV1(label.TraefikBackendLoadBalancerStickinessCookieName, ""), - "hasMaxConnLabels": hasMaxConnLabelsV1, - "getMaxConnExtractorFunc": getFuncStringV1(label.TraefikBackendMaxConnExtractorFunc, label.DefaultBackendMaxconnExtractorFunc), - "getMaxConnAmount": getFuncInt64V1(label.TraefikBackendMaxConnAmount, math.MaxInt64), - "hasHealthCheckLabels": hasFuncV1(label.TraefikBackendHealthCheckPath), - "getHealthCheckPath": getFuncStringV1(label.TraefikBackendHealthCheckPath, ""), - "getHealthCheckInterval": getFuncStringV1(label.TraefikBackendHealthCheckInterval, ""), - - // Frontend functions - "getServiceNames": getServiceNamesV1, - "getServiceNameSuffix": getSegmentNameSuffix, - "getPassHostHeader": getFuncBoolServiceV1(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeader), - "getPassTLSCert": getFuncBoolServiceV1(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert), - "getPriority": getFuncIntServiceV1(label.SuffixFrontendPriority, label.DefaultFrontendPriority), - "getEntryPoints": getFuncSliceStringServiceV1(label.SuffixFrontendEntryPoints), - "getFrontendRule": p.getFrontendRuleV1, - "getFrontendName": p.getFrontendNameV1, - "getBasicAuth": getFuncSliceStringServiceV1(label.SuffixFrontendAuthBasic), - "getWhitelistSourceRange": getFuncSliceStringServiceV1(label.SuffixFrontendWhitelistSourceRange), - "getWhiteList": getWhiteListV1, - } - - filteredApps := fun.Filter(p.applicationFilter, applications.Apps).([]marathon.Application) - for i, app := range filteredApps { - filteredApps[i].Tasks = fun.Filter(func(task *marathon.Task) bool { - filtered := p.taskFilter(*task, app) - if filtered { - logIllegalServicesV1(*task, app) - } - return filtered - }, app.Tasks).([]*marathon.Task) - } - - templateObjects := struct { - Applications []marathon.Application - Domain string - }{ - Applications: filteredApps, - Domain: p.Domain, - } - - configuration, err := p.GetConfiguration("templates/marathon-v1.tmpl", MarathonFuncMap, templateObjects) - if err != nil { - log.Errorf("Failed to render Marathon configuration template: %v", err) - } - return configuration -} - -// logIllegalServicesV1 logs illegal service configurations. -// While we cannot filter on the service level, they will eventually get -// rejected once the server configuration is rendered. -// Deprecated -func logIllegalServicesV1(task marathon.Task, app marathon.Application) { - for _, serviceName := range getServiceNamesV1(app) { - // Check for illegal/missing ports. - if _, err := processPortsV1(app, task, serviceName); err != nil { - log.Warnf("%s has an illegal configuration: no proper port available", identifierV1(app, task, serviceName)) - continue - } - - // Check for illegal port label combinations. - labels := getLabelsV1(app, serviceName) - hasPortLabel := label.Has(labels, getLabelNameV1(serviceName, label.SuffixPort)) - hasPortIndexLabel := label.Has(labels, getLabelNameV1(serviceName, label.SuffixPortIndex)) - if hasPortLabel && hasPortIndexLabel { - log.Warnf("%s has both port and port index specified; port will take precedence", identifierV1(app, task, serviceName)) - } - } -} - -// Deprecated -func (p *Provider) getBackendNameV1(application marathon.Application, serviceName string) string { - labels := getLabelsV1(application, serviceName) - lblBackend := getLabelNameV1(serviceName, label.SuffixBackend) - value := label.GetStringValue(labels, lblBackend, "") - if len(value) > 0 { - return provider.Normalize("backend" + value) - } - return provider.Normalize("backend" + application.ID + getSegmentNameSuffix(serviceName)) -} - -// Deprecated -func (p *Provider) getFrontendNameV1(application marathon.Application, serviceName string) string { - return provider.Normalize("frontend" + application.ID + getSegmentNameSuffix(serviceName)) -} - -// getFrontendRuleV1 returns the frontend rule for the specified application, using -// its label. If service is provided, it will look for serviceName label before generic one. -// It returns a default one (Host) if the label is not present. -// Deprecated -func (p *Provider) getFrontendRuleV1(application marathon.Application, serviceName string) string { - labels := getLabelsV1(application, serviceName) - lblFrontendRule := getLabelNameV1(serviceName, label.SuffixFrontendRule) - if value := label.GetStringValue(labels, lblFrontendRule, ""); len(value) > 0 { - return value - } - - if p.MarathonLBCompatibility { - if value := label.GetStringValue(stringValueMap(application.Labels), labelLbCompatibility, ""); len(value) > 0 { - return "Host:" + value - } - } - - domain := label.GetStringValue(labels, label.SuffixDomain, p.Domain) - if len(serviceName) > 0 { - return "Host:" + strings.ToLower(provider.Normalize(serviceName)) + "." + p.getSubDomain(application.ID) + "." + domain - } - return "Host:" + p.getSubDomain(application.ID) + "." + domain -} - -// Deprecated -func (p *Provider) getBackendServerV1(task marathon.Task, application marathon.Application) string { - networks := application.Networks - var hostFlag bool - - if networks == nil { - hostFlag = application.IPAddressPerTask == nil - } else { - hostFlag = (*networks)[0].Mode != marathon.ContainerNetworkMode - } - - if hostFlag || p.ForceTaskHostname { - return task.Host - } - - numTaskIPAddresses := len(task.IPAddresses) - - switch numTaskIPAddresses { - case 0: - log.Errorf("Missing IP address for Marathon application %s on task %s", application.ID, task.ID) - return "" - case 1: - return task.IPAddresses[0].IPAddress - default: - ipAddressIdx := label.GetIntValue(stringValueMap(application.Labels), labelIPAddressIdx, math.MinInt32) - - if ipAddressIdx == math.MinInt32 { - log.Errorf("Found %d task IP addresses but missing IP address index for Marathon application %s on task %s", - numTaskIPAddresses, application.ID, task.ID) - return "" - } - if ipAddressIdx < 0 || ipAddressIdx > numTaskIPAddresses { - log.Errorf("Cannot use IP address index to select from %d task IP addresses for Marathon application %s on task %s", - numTaskIPAddresses, application.ID, task.ID) - return "" - } - - return task.IPAddresses[ipAddressIdx].IPAddress - } -} - -// getServiceNamesV1 returns a list of service names for a given application -// An empty name "" will be added if no service specific properties exist, -// as an indication that there are no sub-services, but only main application -// Deprecated -func getServiceNamesV1(application marathon.Application) []string { - labelServiceProperties := label.ExtractServicePropertiesP(application.Labels) - - var names []string - for k := range labelServiceProperties { - names = append(names, k) - } - - // An empty name "" will be added if no service specific properties exist, - // as an indication that there are no sub-services, but only main application - if len(names) == 0 { - names = append(names, defaultService) - } - return names -} - -// Deprecated -func identifierV1(app marathon.Application, task marathon.Task, serviceName string) string { - id := fmt.Sprintf("Marathon task %s from application %s", task.ID, app.ID) - if serviceName != "" { - id += fmt.Sprintf(" (service: %s)", serviceName) - } - return id -} - -// Deprecated -func hasLoadBalancerLabelsV1(application marathon.Application) bool { - method := label.Has(stringValueMap(application.Labels), label.TraefikBackendLoadBalancerMethod) - sticky := label.Has(stringValueMap(application.Labels), label.TraefikBackendLoadBalancerSticky) - stickiness := label.Has(stringValueMap(application.Labels), label.TraefikBackendLoadBalancerStickiness) - return method || sticky || stickiness -} - -// Deprecated -func hasMaxConnLabelsV1(application marathon.Application) bool { - mca := label.Has(stringValueMap(application.Labels), label.TraefikBackendMaxConnAmount) - mcef := label.Has(stringValueMap(application.Labels), label.TraefikBackendMaxConnExtractorFunc) - return mca && mcef -} - -// TODO: Deprecated -// replaced by Stickiness -// Deprecated -func getStickyV1(application marathon.Application) bool { - if label.Has(stringValueMap(application.Labels), label.TraefikBackendLoadBalancerSticky) { - log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness) - } - return label.GetBoolValue(stringValueMap(application.Labels), label.TraefikBackendLoadBalancerSticky, false) -} - -// Deprecated -func getPortV1(task marathon.Task, application marathon.Application, serviceName string) string { - port, err := processPortsV1(application, task, serviceName) - if err != nil { - log.Errorf("Unable to process ports for %s: %s", identifierV1(application, task, serviceName), err) - return "" - } - - return strconv.Itoa(port) -} - -// processPortsV1 returns the configured port. -// An explicitly specified port is preferred. If none is specified, it selects -// one of the available port. The first such found port is returned unless an -// optional index is provided. -// Deprecated -func processPortsV1(application marathon.Application, task marathon.Task, serviceName string) (int, error) { - labels := getLabelsV1(application, serviceName) - lblPort := getLabelNameV1(serviceName, label.SuffixPort) - - if label.Has(labels, lblPort) { - port := label.GetIntValue(labels, lblPort, 0) - - if port <= 0 { - return 0, fmt.Errorf("explicitly specified port %d must be larger than zero", port) - } else if port > 0 { - return port, nil - } - } - - ports := retrieveAvailablePortsV1(application, task) - if len(ports) == 0 { - return 0, errors.New("no port found") - } - - lblPortIndex := getLabelNameV1(serviceName, label.SuffixPortIndex) - portIndex := label.GetIntValue(labels, lblPortIndex, 0) - if portIndex < 0 || portIndex > len(ports)-1 { - return 0, fmt.Errorf("index %d must be within range (0, %d)", portIndex, len(ports)-1) - } - return ports[portIndex], nil -} - -// Deprecated -func retrieveAvailablePortsV1(application marathon.Application, task marathon.Task) []int { - // Using default port configuration - if len(task.Ports) > 0 { - return task.Ports - } - - // Using port definition if available - if application.PortDefinitions != nil && len(*application.PortDefinitions) > 0 { - var ports []int - for _, def := range *application.PortDefinitions { - if def.Port != nil { - ports = append(ports, *def.Port) - } - } - return ports - } - // If using IP-per-task using this port definition - if application.IPAddressPerTask != nil && len(*(application.IPAddressPerTask.Discovery).Ports) > 0 { - var ports []int - for _, def := range *(application.IPAddressPerTask.Discovery).Ports { - ports = append(ports, def.Number) - } - return ports - } - - return []int{} -} - -// Deprecated -func (p *Provider) getServersV1(application marathon.Application, serviceName string) map[string]types.Server { - var servers map[string]types.Server - - for _, task := range application.Tasks { - host := p.getBackendServerV1(*task, application) - if len(host) == 0 { - continue - } - - if servers == nil { - servers = make(map[string]types.Server) - } - - labels := getLabelsV1(application, serviceName) - - port := getPortV1(*task, application, serviceName) - protocol := label.GetStringValue(labels, getLabelNameV1(serviceName, label.SuffixProtocol), label.DefaultProtocol) - - serverName := provider.Normalize("server-" + task.ID + getSegmentNameSuffix(serviceName)) - servers[serverName] = types.Server{ - URL: fmt.Sprintf("%s://%s:%v", protocol, host, port), - Weight: label.GetIntValue(labels, getLabelNameV1(serviceName, label.SuffixWeight), label.DefaultWeight), - } - } - - return servers -} - -// Deprecated -func getWhiteListV1(application marathon.Application, serviceName string) *types.WhiteList { - labels := getLabelsV1(application, serviceName) - - ranges := label.GetSliceStringValue(labels, getLabelNameV1(serviceName, label.SuffixFrontendWhiteListSourceRange)) - if len(ranges) > 0 { - return &types.WhiteList{ - SourceRange: ranges, - UseXForwardedFor: label.GetBoolValue(labels, getLabelNameV1(serviceName, label.SuffixFrontendWhiteListUseXForwardedFor), false), - } - } - - return nil -} - -// Label functions - -// Deprecated -func getLabelsV1(application marathon.Application, serviceName string) map[string]string { - if len(serviceName) > 0 { - return label.ExtractServicePropertiesP(application.Labels)[serviceName] - } - - if application.Labels != nil { - return *application.Labels - } - - return make(map[string]string) -} - -// Deprecated -func getLabelNameV1(serviceName string, suffix string) string { - if len(serviceName) != 0 { - return suffix - } - return label.Prefix + suffix -} - -// Deprecated -func hasFuncV1(labelName string) func(application marathon.Application) bool { - return func(application marathon.Application) bool { - return label.Has(stringValueMap(application.Labels), labelName) - } -} - -// Deprecated -func getFuncStringServiceV1(labelName string, defaultValue string) func(application marathon.Application, serviceName string) string { - return func(application marathon.Application, serviceName string) string { - labels := getLabelsV1(application, serviceName) - lbName := getLabelNameV1(serviceName, labelName) - return label.GetStringValue(labels, lbName, defaultValue) - } -} - -// Deprecated -func getFuncBoolServiceV1(labelName string, defaultValue bool) func(application marathon.Application, serviceName string) bool { - return func(application marathon.Application, serviceName string) bool { - labels := getLabelsV1(application, serviceName) - lbName := getLabelNameV1(serviceName, labelName) - return label.GetBoolValue(labels, lbName, defaultValue) - } -} - -// Deprecated -func getFuncIntServiceV1(labelName string, defaultValue int) func(application marathon.Application, serviceName string) int { - return func(application marathon.Application, serviceName string) int { - labels := getLabelsV1(application, serviceName) - lbName := getLabelNameV1(serviceName, labelName) - return label.GetIntValue(labels, lbName, defaultValue) - } -} - -// Deprecated -func getFuncSliceStringServiceV1(labelName string) func(application marathon.Application, serviceName string) []string { - return func(application marathon.Application, serviceName string) []string { - labels := getLabelsV1(application, serviceName) - return label.GetSliceStringValue(labels, getLabelNameV1(serviceName, labelName)) - } -} - -// Deprecated -func getFuncStringV1(labelName string, defaultValue string) func(application marathon.Application) string { - return func(application marathon.Application) string { - return label.GetStringValue(stringValueMap(application.Labels), labelName, defaultValue) - } -} - -// Deprecated -func getFuncInt64V1(labelName string, defaultValue int64) func(application marathon.Application) int64 { - return func(application marathon.Application) int64 { - return label.GetInt64Value(stringValueMap(application.Labels), labelName, defaultValue) - } -} diff --git a/provider/marathon/deprecated_config_test.go b/provider/marathon/deprecated_config_test.go deleted file mode 100644 index b4d07846f..000000000 --- a/provider/marathon/deprecated_config_test.go +++ /dev/null @@ -1,895 +0,0 @@ -package marathon - -import ( - "testing" - - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/assert" -) - -func TestGetConfigurationAPIErrorsV1(t *testing.T) { - fakeClient := newFakeClient(true, marathon.Applications{}) - - p := &Provider{ - marathonClient: fakeClient, - } - p.TemplateVersion = 1 - - actualConfig := p.getConfiguration() - fakeClient.AssertExpectations(t) - - if actualConfig != nil { - t.Errorf("configuration should have been nil, got %v", actualConfig) - } -} - -func TestBuildConfigurationV1(t *testing.T) { - testCases := []struct { - desc string - application marathon.Application - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - }{ - { - desc: "simple application", - application: application( - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - expectedFrontends: map[string]*types.Frontend{ - "frontend-app": { - Backend: "backend-app", - Routes: map[string]types.Route{ - "route-host-app": { - Rule: "Host:app.marathon.localhost", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - EntryPoints: []string{}, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-app": { - Servers: map[string]types.Server{ - "server-task": { - URL: "http://localhost:80", - Weight: label.DefaultWeight, - }, - }, - CircuitBreaker: nil, - }, - }, - }, - { - desc: "filtered task", - application: application( - appPorts(80), - withTasks(localhostTask(taskPorts(80), taskState(taskStateStaging))), - ), - expectedFrontends: map[string]*types.Frontend{ - "frontend-app": { - Backend: "backend-app", - Routes: map[string]types.Route{ - "route-host-app": { - Rule: "Host:app.marathon.localhost", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - EntryPoints: []string{}, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-app": {}, - }, - }, - { - desc: "max connection extractor function label only", - application: application( - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - - withLabel(label.TraefikBackendMaxConnExtractorFunc, "client.ip"), - ), - expectedFrontends: map[string]*types.Frontend{ - "frontend-app": { - Backend: "backend-app", - Routes: map[string]types.Route{ - "route-host-app": { - Rule: "Host:app.marathon.localhost", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - EntryPoints: []string{}, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-app": { - Servers: map[string]types.Server{ - "server-task": { - URL: "http://localhost:80", - Weight: label.DefaultWeight, - }, - }, - MaxConn: nil, - }, - }, - }, - { - desc: "multiple ports", - application: application( - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - ), - expectedFrontends: map[string]*types.Frontend{ - "frontend-app": { - Backend: "backend-app", - Routes: map[string]types.Route{ - "route-host-app": { - Rule: "Host:app.marathon.localhost", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - EntryPoints: []string{}, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-app": { - Servers: map[string]types.Server{ - "server-task": { - URL: "http://localhost:80", - Weight: label.DefaultWeight, - }, - }, - }, - }, - }, - { - desc: "with all labels", - application: application( - appPorts(80), - withTasks(task(host("127.0.0.1"), taskPorts(80))), - - withLabel(label.TraefikPort, "666"), - withLabel(label.TraefikProtocol, "https"), - withLabel(label.TraefikWeight, "12"), - - withLabel(label.TraefikBackend, "foobar"), - - withLabel(label.TraefikBackendCircuitBreakerExpression, "NetworkErrorRatio() > 0.5"), - withLabel(label.TraefikBackendHealthCheckPath, "/health"), - withLabel(label.TraefikBackendHealthCheckInterval, "6"), - withLabel(label.TraefikBackendLoadBalancerMethod, "drr"), - withLabel(label.TraefikBackendLoadBalancerSticky, "true"), - withLabel(label.TraefikBackendLoadBalancerStickiness, "true"), - withLabel(label.TraefikBackendLoadBalancerStickinessCookieName, "chocolate"), - withLabel(label.TraefikBackendMaxConnAmount, "666"), - withLabel(label.TraefikBackendMaxConnExtractorFunc, "client.ip"), - - withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - withLabel(label.TraefikFrontendEntryPoints, "http,https"), - withLabel(label.TraefikFrontendPassHostHeader, "true"), - withLabel(label.TraefikFrontendPriority, "666"), - withLabel(label.TraefikFrontendRule, "Host:traefik.io"), - ), - expectedFrontends: map[string]*types.Frontend{ - "frontend-app": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backendfoobar", - Routes: map[string]types.Route{ - "route-host-app": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backendfoobar": { - Servers: map[string]types.Server{ - "server-task": { - URL: "https://127.0.0.1:666", - Weight: 12, - }, - }, - CircuitBreaker: &types.CircuitBreaker{ - Expression: "NetworkErrorRatio() > 0.5", - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - Sticky: true, - Stickiness: &types.Stickiness{ - CookieName: "chocolate", - }, - }, - MaxConn: &types.MaxConn{ - Amount: 666, - ExtractorFunc: "client.ip", - }, - HealthCheck: &types.HealthCheck{ - Path: "/health", - Interval: "6", - }, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - test.application.ID = "/app" - - for _, task := range test.application.Tasks { - task.ID = "task" - if task.State == "" { - task.State = "TASK_RUNNING" - } - } - - p := &Provider{ - Domain: "marathon.localhost", - ExposedByDefault: true, - } - - actualConfig := p.buildConfigurationV1(withApplications(test.application)) - - assert.NotNil(t, actualConfig) - assert.Equal(t, test.expectedBackends, actualConfig.Backends) - assert.Equal(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestBuildConfigurationServicesV1(t *testing.T) { - testCases := []struct { - desc string - application marathon.Application - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - }{ - { - desc: "multiple ports with services", - application: application( - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - - withLabel(label.TraefikBackendMaxConnAmount, "1000"), - withLabel(label.TraefikBackendMaxConnExtractorFunc, "client.ip"), - withSegmentLabel(label.TraefikPort, "80", "web"), - withSegmentLabel(label.TraefikPort, "81", "admin"), - withLabel("traefik..port", "82"), // This should be ignored, as it fails to match the servicesPropertiesRegexp regex. - withSegmentLabel(label.TraefikFrontendRule, "Host:web.app.marathon.localhost", "web"), - withSegmentLabel(label.TraefikFrontendRule, "Host:admin.app.marathon.localhost", "admin"), - ), - expectedFrontends: map[string]*types.Frontend{ - "frontend-app-service-web": { - Backend: "backend-app-service-web", - Routes: map[string]types.Route{ - `route-host-app-service-web`: { - Rule: "Host:web.app.marathon.localhost", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - EntryPoints: []string{}, - }, - "frontend-app-service-admin": { - Backend: "backend-app-service-admin", - Routes: map[string]types.Route{ - `route-host-app-service-admin`: { - Rule: "Host:admin.app.marathon.localhost", - }, - }, - PassHostHeader: true, - BasicAuth: []string{}, - EntryPoints: []string{}, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-app-service-web": { - Servers: map[string]types.Server{ - "server-task-service-web": { - URL: "http://localhost:80", - Weight: label.DefaultWeight, - }, - }, - MaxConn: &types.MaxConn{ - Amount: 1000, - ExtractorFunc: "client.ip", - }, - }, - "backend-app-service-admin": { - Servers: map[string]types.Server{ - "server-task-service-admin": { - URL: "http://localhost:81", - Weight: label.DefaultWeight, - }, - }, - MaxConn: &types.MaxConn{ - Amount: 1000, - ExtractorFunc: "client.ip", - }, - }, - }, - }, - { - desc: "when all labels are set", - application: application( - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - - withLabel(label.TraefikBackendCircuitBreakerExpression, "NetworkErrorRatio() > 0.5"), - withLabel(label.TraefikBackendHealthCheckPath, "/health"), - withLabel(label.TraefikBackendHealthCheckInterval, "6"), - withLabel(label.TraefikBackendLoadBalancerMethod, "drr"), - withLabel(label.TraefikBackendLoadBalancerSticky, "true"), - withLabel(label.TraefikBackendLoadBalancerStickiness, "true"), - withLabel(label.TraefikBackendLoadBalancerStickinessCookieName, "chocolate"), - withLabel(label.TraefikBackendMaxConnAmount, "666"), - withLabel(label.TraefikBackendMaxConnExtractorFunc, "client.ip"), - - withSegmentLabel(label.TraefikPort, "80", "containous"), - withSegmentLabel(label.TraefikProtocol, "https", "containous"), - withSegmentLabel(label.TraefikWeight, "12", "containous"), - - withSegmentLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", "containous"), - withSegmentLabel(label.TraefikFrontendEntryPoints, "http,https", "containous"), - withSegmentLabel(label.TraefikFrontendPassHostHeader, "true", "containous"), - withSegmentLabel(label.TraefikFrontendPriority, "666", "containous"), - withSegmentLabel(label.TraefikFrontendRule, "Host:traefik.io", "containous"), - ), - expectedFrontends: map[string]*types.Frontend{ - "frontend-app-service-containous": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backend-app-service-containous", - Routes: map[string]types.Route{ - "route-host-app-service-containous": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-app-service-containous": { - Servers: map[string]types.Server{ - "server-task-service-containous": { - URL: "https://localhost:80", - Weight: 12, - }, - }, - CircuitBreaker: &types.CircuitBreaker{ - Expression: "NetworkErrorRatio() > 0.5", - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - Sticky: true, - Stickiness: &types.Stickiness{ - CookieName: "chocolate", - }, - }, - MaxConn: &types.MaxConn{ - Amount: 666, - ExtractorFunc: "client.ip", - }, - HealthCheck: &types.HealthCheck{ - Path: "/health", - Interval: "6", - }, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - test.application.ID = "/app" - - for _, task := range test.application.Tasks { - task.ID = "task" - if task.State == "" { - task.State = "TASK_RUNNING" - } - } - - p := &Provider{ - Domain: "marathon.localhost", - ExposedByDefault: true, - } - - actualConfig := p.buildConfigurationV1(withApplications(test.application)) - - assert.NotNil(t, actualConfig) - assert.Equal(t, test.expectedBackends, actualConfig.Backends) - assert.Equal(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestGetPortV1(t *testing.T) { - testCases := []struct { - desc string - application marathon.Application - task marathon.Task - serviceName string - expected string - }{ - { - desc: "port missing", - application: application(), - task: task(), - expected: "", - }, - { - desc: "numeric port", - application: application(withLabel(label.TraefikPort, "80")), - task: task(), - expected: "80", - }, - { - desc: "string port", - application: application(withLabel(label.TraefikPort, "foobar")), - task: task(taskPorts(80)), - expected: "", - }, - { - desc: "negative port", - application: application(withLabel(label.TraefikPort, "-1")), - task: task(taskPorts(80)), - expected: "", - }, - { - desc: "task port available", - application: application(), - task: task(taskPorts(80)), - expected: "80", - }, - { - desc: "port definition available", - application: application( - portDefinition(443), - ), - task: task(), - expected: "443", - }, - { - desc: "IP-per-task port available", - application: application(ipAddrPerTask(8000)), - task: task(), - expected: "8000", - }, - { - desc: "multiple task ports available", - application: application(), - task: task(taskPorts(80, 443)), - expected: "80", - }, - { - desc: "numeric port index specified", - application: application(withLabel(label.TraefikPortIndex, "1")), - task: task(taskPorts(80, 443)), - expected: "443", - }, - { - desc: "string port index specified", - application: application(withLabel(label.TraefikPortIndex, "foobar")), - task: task(taskPorts(80)), - expected: "80", - }, - { - desc: "port and port index specified", - application: application( - withLabel(label.TraefikPort, "80"), - withLabel(label.TraefikPortIndex, "1"), - ), - task: task(taskPorts(80, 443)), - expected: "80", - }, - { - desc: "task and application ports specified", - application: application(appPorts(9999)), - task: task(taskPorts(7777)), - expected: "7777", - }, - { - desc: "multiple task ports with service index available", - application: application(withLabel(label.Prefix+"http.portIndex", "0")), - task: task(taskPorts(80, 443)), - serviceName: "http", - expected: "80", - }, - { - desc: "multiple task ports with service port available", - application: application(withLabel(label.Prefix+"https.port", "443")), - task: task(taskPorts(80, 443)), - serviceName: "https", - expected: "443", - }, - { - desc: "multiple task ports with services but default port available", - application: application(withLabel(label.Prefix+"http.weight", "100")), - task: task(taskPorts(80, 443)), - serviceName: "http", - expected: "80", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := getPortV1(test.task, test.application, test.serviceName) - - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestGetFrontendRuleV1(t *testing.T) { - testCases := []struct { - desc string - application marathon.Application - serviceName string - expected string - marathonLBCompatibility bool - }{ - { - desc: "label missing", - application: application(appID("test")), - marathonLBCompatibility: true, - expected: "Host:test.marathon.localhost", - }, - { - desc: "HAProxy vhost available and LB compat disabled", - application: application( - appID("test"), - withLabel("HAPROXY_0_VHOST", "foo.bar"), - ), - marathonLBCompatibility: false, - expected: "Host:test.marathon.localhost", - }, - { - desc: "HAProxy vhost available and LB compat enabled", - application: application(withLabel("HAPROXY_0_VHOST", "foo.bar")), - marathonLBCompatibility: true, - expected: "Host:foo.bar", - }, - { - desc: "frontend rule available", - - application: application( - withLabel(label.TraefikFrontendRule, "Host:foo.bar"), - withLabel("HAPROXY_0_VHOST", "unused"), - ), - marathonLBCompatibility: true, - expected: "Host:foo.bar", - }, - { - desc: "service label existing", - application: application(withSegmentLabel(label.TraefikFrontendRule, "Host:foo.bar", "app")), - serviceName: "app", - marathonLBCompatibility: true, - expected: "Host:foo.bar", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - p := &Provider{ - Domain: "marathon.localhost", - MarathonLBCompatibility: test.marathonLBCompatibility, - } - - actual := p.getFrontendRuleV1(test.application, test.serviceName) - - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestGetBackendV1(t *testing.T) { - testCases := []struct { - desc string - application marathon.Application - serviceName string - expected string - }{ - { - desc: "label missing", - application: application(appID("/group/app")), - expected: "backend-group-app", - }, - { - desc: "label existing", - application: application(withLabel(label.TraefikBackend, "bar")), - expected: "backendbar", - }, - { - desc: "service label existing", - application: application(withSegmentLabel(label.TraefikBackend, "bar", "app")), - serviceName: "app", - expected: "backendbar", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - p := &Provider{} - - actual := p.getBackendNameV1(test.application, test.serviceName) - - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestGetBackendServerV1(t *testing.T) { - host := "host" - testCases := []struct { - desc string - application marathon.Application - task marathon.Task - forceTaskHostname bool - expectedServer string - }{ - { - desc: "application without IP-per-task", - application: application(), - expectedServer: host, - }, - { - desc: "task hostname override", - application: application(ipAddrPerTask(8000)), - forceTaskHostname: true, - expectedServer: host, - }, - { - desc: "task IP address missing", - application: application(ipAddrPerTask(8000)), - task: task(), - expectedServer: "", - }, - { - desc: "single task IP address", - application: application(ipAddrPerTask(8000)), - task: task(ipAddresses("1.1.1.1")), - expectedServer: "1.1.1.1", - }, - { - desc: "multiple task IP addresses without index label", - application: application(ipAddrPerTask(8000)), - task: task(ipAddresses("1.1.1.1", "2.2.2.2")), - expectedServer: "", - }, - { - desc: "multiple task IP addresses with invalid index label", - application: application( - withLabel("traefik.ipAddressIdx", "invalid"), - ipAddrPerTask(8000), - ), - task: task(ipAddresses("1.1.1.1", "2.2.2.2")), - expectedServer: "", - }, - { - desc: "multiple task IP addresses with valid index label", - application: application( - withLabel("traefik.ipAddressIdx", "1"), - ipAddrPerTask(8000), - ), - task: task(ipAddresses("1.1.1.1", "2.2.2.2")), - expectedServer: "2.2.2.2", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - p := &Provider{ForceTaskHostname: test.forceTaskHostname} - test.task.Host = host - - actualServer := p.getBackendServerV1(test.task, test.application) - - assert.Equal(t, test.expectedServer, actualServer) - }) - } -} - -func TestGetStickyV1(t *testing.T) { - testCases := []struct { - desc string - application marathon.Application - expected bool - }{ - { - desc: "label missing", - application: application(), - expected: false, - }, - { - desc: "label existing", - application: application(withLabel(label.TraefikBackendLoadBalancerSticky, "true")), - expected: true, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := getStickyV1(test.application) - if actual != test.expected { - t.Errorf("actual %v, expected %v", actual, test.expected) - } - }) - } -} - -func TestGetServersV1(t *testing.T) { - testCases := []struct { - desc string - application marathon.Application - segmentName string - expected map[string]types.Server - }{ - { - desc: "should return nil when no task", - application: application(ipAddrPerTask(80)), - expected: nil, - }, - { - desc: "should return nil when all hosts are empty", - application: application( - withTasks( - task(ipAddresses("1.1.1.1"), withTaskID("A"), taskPorts(80)), - task(ipAddresses("1.1.1.2"), withTaskID("B"), taskPorts(80)), - task(ipAddresses("1.1.1.3"), withTaskID("C"), taskPorts(80))), - ), - expected: nil, - }, - { - desc: "with 3 tasks and hosts set", - application: application( - withTasks( - task(ipAddresses("1.1.1.1"), host("2.2.2.2"), withTaskID("A"), taskPorts(80)), - task(ipAddresses("1.1.1.2"), host("2.2.2.2"), withTaskID("B"), taskPorts(81)), - task(ipAddresses("1.1.1.3"), host("2.2.2.2"), withTaskID("C"), taskPorts(82))), - ), - expected: map[string]types.Server{ - "server-A": { - URL: "http://2.2.2.2:80", - Weight: label.DefaultWeight, - }, - "server-B": { - URL: "http://2.2.2.2:81", - Weight: label.DefaultWeight, - }, - "server-C": { - URL: "http://2.2.2.2:82", - Weight: label.DefaultWeight, - }, - }, - }, - { - desc: "with 3 tasks and ipAddrPerTask set", - application: application( - ipAddrPerTask(80), - withTasks( - task(ipAddresses("1.1.1.1"), withTaskID("A"), taskPorts(80)), - task(ipAddresses("1.1.1.2"), withTaskID("B"), taskPorts(80)), - task(ipAddresses("1.1.1.3"), withTaskID("C"), taskPorts(80))), - ), - expected: map[string]types.Server{ - "server-A": { - URL: "http://1.1.1.1:80", - Weight: label.DefaultWeight, - }, - "server-B": { - URL: "http://1.1.1.2:80", - Weight: label.DefaultWeight, - }, - "server-C": { - URL: "http://1.1.1.3:80", - Weight: label.DefaultWeight, - }, - }, - }, - { - desc: "with 3 tasks and bridge network", - application: application( - bridgeNetwork(), - withTasks( - task(ipAddresses("1.1.1.1"), host("2.2.2.2"), withTaskID("A"), taskPorts(80)), - task(ipAddresses("1.1.1.2"), host("2.2.2.2"), withTaskID("B"), taskPorts(81)), - task(ipAddresses("1.1.1.3"), host("2.2.2.2"), withTaskID("C"), taskPorts(82))), - ), - expected: map[string]types.Server{ - "server-A": { - URL: "http://2.2.2.2:80", - Weight: label.DefaultWeight, - }, - "server-B": { - URL: "http://2.2.2.2:81", - Weight: label.DefaultWeight, - }, - "server-C": { - URL: "http://2.2.2.2:82", - Weight: label.DefaultWeight, - }, - }, - }, - { - desc: "with 3 tasks and cni set", - application: application( - containerNetwork(), - withTasks( - task(ipAddresses("1.1.1.1"), withTaskID("A"), taskPorts(80)), - task(ipAddresses("1.1.1.2"), withTaskID("B"), taskPorts(80)), - task(ipAddresses("1.1.1.3"), withTaskID("C"), taskPorts(80))), - ), - expected: map[string]types.Server{ - "server-A": { - URL: "http://1.1.1.1:80", - Weight: label.DefaultWeight, - }, - "server-B": { - URL: "http://1.1.1.2:80", - Weight: label.DefaultWeight, - }, - "server-C": { - URL: "http://1.1.1.3:80", - Weight: label.DefaultWeight, - }, - }, - }, - } - - p := &Provider{} - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := p.getServersV1(test.application, test.segmentName) - - assert.Equal(t, test.expected, actual) - }) - } -} diff --git a/provider/mesos/config.go b/provider/mesos/config.go index 7a379b3a1..4ec8df3e9 100644 --- a/provider/mesos/config.go +++ b/provider/mesos/config.go @@ -21,7 +21,7 @@ type taskData struct { SegmentName string } -func (p *Provider) buildConfigurationV2(tasks []state.Task) *types.Configuration { +func (p *Provider) buildConfiguration(tasks []state.Task) *types.Configuration { var mesosFuncMap = template.FuncMap{ "getDomain": label.GetFuncString(label.TraefikDomain, p.Domain), "getSubDomain": p.getSubDomain, diff --git a/provider/mesos/config_root.go b/provider/mesos/config_root.go deleted file mode 100644 index 487c366ea..000000000 --- a/provider/mesos/config_root.go +++ /dev/null @@ -1,13 +0,0 @@ -package mesos - -import ( - "github.com/containous/traefik/types" - "github.com/mesosphere/mesos-dns/records/state" -) - -func (p *Provider) buildConfiguration(tasks []state.Task) *types.Configuration { - if p.TemplateVersion == 1 { - return p.buildConfigurationV1(tasks) - } - return p.buildConfigurationV2(tasks) -} diff --git a/provider/mesos/config_test.go b/provider/mesos/config_test.go index 6b5af71d7..3fb335e32 100644 --- a/provider/mesos/config_test.go +++ b/provider/mesos/config_test.go @@ -555,7 +555,7 @@ func TestBuildConfiguration(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - actualConfig := p.buildConfigurationV2(test.tasks) + actualConfig := p.buildConfiguration(test.tasks) require.NotNil(t, actualConfig) assert.Equal(t, test.expectedBackends, actualConfig.Backends) @@ -909,7 +909,7 @@ func TestBuildConfigurationSegments(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - actualConfig := p.buildConfigurationV2(test.tasks) + actualConfig := p.buildConfiguration(test.tasks) require.NotNil(t, actualConfig) assert.Equal(t, test.expectedBackends, actualConfig.Backends) diff --git a/provider/mesos/deprecated_config.go b/provider/mesos/deprecated_config.go deleted file mode 100644 index 71c1fb2b6..000000000 --- a/provider/mesos/deprecated_config.go +++ /dev/null @@ -1,329 +0,0 @@ -package mesos - -import ( - "fmt" - "math" - "strconv" - "strings" - "text/template" - - "github.com/BurntSushi/ty/fun" - "github.com/containous/traefik/log" - "github.com/containous/traefik/provider" - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/mesosphere/mesos-dns/records/state" -) - -func (p *Provider) buildConfigurationV1(tasks []state.Task) *types.Configuration { - var mesosFuncMap = template.FuncMap{ - "getDomain": getFuncStringValueV1(label.TraefikDomain, p.Domain), - "getID": getIDV1, - - // Backend functions - "getBackendName": getBackendNameV1, - "getHost": p.getHostV1, - "getProtocol": getFuncApplicationStringValueV1(label.TraefikProtocol, label.DefaultProtocol), - "getWeight": getFuncApplicationIntValueV1(label.TraefikWeight, label.DefaultWeight), - "getBackend": getBackendV1, - "getPort": p.getPort, - - // Frontend functions - "getFrontendBackend": getBackendNameV1, - "getFrontEndName": getFrontendNameV1, - "getEntryPoints": getFuncSliceStringValueV1(label.TraefikFrontendEntryPoints), - "getBasicAuth": getFuncSliceStringValueV1(label.TraefikFrontendAuthBasic), - "getPriority": getFuncIntValueV1(label.TraefikFrontendPriority, label.DefaultFrontendPriority), - "getPassHostHeader": getFuncBoolValueV1(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), - "getFrontendRule": p.getFrontendRuleV1, - } - - // filter tasks - filteredTasks := fun.Filter(func(task state.Task) bool { - return taskFilterV1(task, p.ExposedByDefault) - }, tasks).([]state.Task) - - // Deprecated - var filteredApps []state.Task - uniqueApps := make(map[string]struct{}) - for _, task := range filteredTasks { - if _, ok := uniqueApps[task.DiscoveryInfo.Name]; !ok { - uniqueApps[task.DiscoveryInfo.Name] = struct{}{} - filteredApps = append(filteredApps, task) - } - } - - appsTasks := make(map[string][]state.Task) - for _, task := range filteredTasks { - if _, ok := appsTasks[task.DiscoveryInfo.Name]; !ok { - appsTasks[task.DiscoveryInfo.Name] = []state.Task{task} - } else { - appsTasks[task.DiscoveryInfo.Name] = append(appsTasks[task.DiscoveryInfo.Name], task) - } - } - - templateObjects := struct { - ApplicationsTasks map[string][]state.Task - Applications []state.Task // Deprecated - Tasks []state.Task // Deprecated - Domain string - }{ - ApplicationsTasks: appsTasks, - Applications: filteredApps, // Deprecated - Tasks: filteredTasks, // Deprecated - Domain: p.Domain, - } - - configuration, err := p.GetConfiguration("templates/mesos-v1.tmpl", mesosFuncMap, templateObjects) - if err != nil { - log.Error(err) - } - return configuration -} - -// Deprecated -func taskFilterV1(task state.Task, exposedByDefaultFlag bool) bool { - if len(task.DiscoveryInfo.Ports.DiscoveryPorts) == 0 { - log.Debugf("Filtering Mesos task without port %s", task.Name) - return false - } - - if !isEnabledV1(task, exposedByDefaultFlag) { - log.Debugf("Filtering disabled Mesos task %s", task.DiscoveryInfo.Name) - return false - } - - // filter indeterminable task port - portIndexLabel := getStringValueV1(task, label.TraefikPortIndex, "") - portValueLabel := getStringValueV1(task, label.TraefikPort, "") - if portIndexLabel != "" && portValueLabel != "" { - log.Debugf("Filtering Mesos task %s specifying both %q' and %q labels", task.Name, label.TraefikPortIndex, label.TraefikPort) - return false - } - if portIndexLabel != "" { - index, err := strconv.Atoi(portIndexLabel) - if err != nil || index < 0 || index > len(task.DiscoveryInfo.Ports.DiscoveryPorts)-1 { - log.Debugf("Filtering Mesos task %s with unexpected value for %q label", task.Name, label.TraefikPortIndex) - return false - } - } - if portValueLabel != "" { - port, err := strconv.Atoi(portValueLabel) - if err != nil { - log.Debugf("Filtering Mesos task %s with unexpected value for %q label", task.Name, label.TraefikPort) - return false - } - - var foundPort bool - for _, exposedPort := range task.DiscoveryInfo.Ports.DiscoveryPorts { - if port == exposedPort.Number { - foundPort = true - break - } - } - - if !foundPort { - log.Debugf("Filtering Mesos task %s without a matching port for %q label", task.Name, label.TraefikPort) - return false - } - } - - // filter healthChecks - if task.Statuses != nil && len(task.Statuses) > 0 && task.Statuses[0].Healthy != nil && !*task.Statuses[0].Healthy { - log.Debugf("Filtering Mesos task %s with bad healthCheck", task.DiscoveryInfo.Name) - return false - - } - return true -} - -// Deprecated -func getIDV1(task state.Task) string { - return provider.Normalize(task.ID) -} - -// Deprecated -func getBackendV1(task state.Task, apps []state.Task) string { - _, err := getApplicationV1(task, apps) - if err != nil { - log.Error(err) - return "" - } - return getBackendNameV1(task) -} - -// Deprecated -func getBackendNameV1(task state.Task) string { - if value := getStringValueV1(task, label.TraefikBackend, ""); len(value) > 0 { - return value - } - return provider.Normalize(task.DiscoveryInfo.Name) -} - -// Deprecated -func getFrontendNameV1(task state.Task) string { - // TODO task.ID -> task.Name + task.ID - return provider.Normalize(task.ID) -} - -// Deprecated -func (p *Provider) getPort(task state.Task, applications []state.Task) string { - _, err := getApplicationV1(task, applications) - if err != nil { - log.Error(err) - return "" - } - - plv := getIntValueV1(task, label.TraefikPortIndex, math.MinInt32, len(task.DiscoveryInfo.Ports.DiscoveryPorts)-1) - if plv >= 0 { - return strconv.Itoa(task.DiscoveryInfo.Ports.DiscoveryPorts[plv].Number) - } - - if pv := getStringValueV1(task, label.TraefikPort, ""); len(pv) > 0 { - return pv - } - - for _, port := range task.DiscoveryInfo.Ports.DiscoveryPorts { - return strconv.Itoa(port.Number) - } - return "" -} - -// getFrontendRuleV1 returns the frontend rule for the specified application, using -// it's label. It returns a default one (Host) if the label is not present. -// Deprecated -func (p *Provider) getFrontendRuleV1(task state.Task) string { - if v := getStringValueV1(task, label.TraefikFrontendRule, ""); len(v) > 0 { - return v - } - - domain := getStringValueV1(task, label.TraefikDomain, p.Domain) - return "Host:" + strings.ToLower(strings.Replace(p.getSubDomain(task.DiscoveryInfo.Name), "_", "-", -1)) + "." + domain -} - -// Deprecated -func (p *Provider) getHostV1(task state.Task) string { - return task.IP(strings.Split(p.IPSources, ",")...) -} - -// Deprecated -func isEnabledV1(task state.Task, exposedByDefault bool) bool { - return getBoolValueV1(task, label.TraefikEnable, exposedByDefault) -} - -// Label functions - -// Deprecated -func getFuncApplicationStringValueV1(labelName string, defaultValue string) func(task state.Task, applications []state.Task) string { - return func(task state.Task, applications []state.Task) string { - _, err := getApplicationV1(task, applications) - if err != nil { - log.Error(err) - return defaultValue - } - - return getStringValueV1(task, labelName, defaultValue) - } -} - -// Deprecated -func getFuncApplicationIntValueV1(labelName string, defaultValue int) func(task state.Task, applications []state.Task) int { - return func(task state.Task, applications []state.Task) int { - _, err := getApplicationV1(task, applications) - if err != nil { - log.Error(err) - return defaultValue - } - - return getIntValueV1(task, labelName, defaultValue, math.MaxInt32) - } -} - -// Deprecated -func getFuncStringValueV1(labelName string, defaultValue string) func(task state.Task) string { - return func(task state.Task) string { - return getStringValueV1(task, labelName, defaultValue) - } -} - -// Deprecated -func getFuncBoolValueV1(labelName string, defaultValue bool) func(task state.Task) bool { - return func(task state.Task) bool { - return getBoolValueV1(task, labelName, defaultValue) - } -} - -// Deprecated -func getFuncIntValueV1(labelName string, defaultValue int) func(task state.Task) int { - return func(task state.Task) int { - return getIntValueV1(task, labelName, defaultValue, math.MaxInt32) - } -} - -// Deprecated -func getFuncSliceStringValueV1(labelName string) func(task state.Task) []string { - return func(task state.Task) []string { - return getSliceStringValueV1(task, labelName) - } -} - -// Deprecated -func getStringValueV1(task state.Task, labelName string, defaultValue string) string { - for _, lbl := range task.Labels { - if lbl.Key == labelName && len(lbl.Value) > 0 { - return lbl.Value - } - } - return defaultValue -} - -// Deprecated -func getBoolValueV1(task state.Task, labelName string, defaultValue bool) bool { - for _, lbl := range task.Labels { - if lbl.Key == labelName { - v, err := strconv.ParseBool(lbl.Value) - if err == nil { - return v - } - } - } - return defaultValue -} - -// Deprecated -func getIntValueV1(task state.Task, labelName string, defaultValue int, maxValue int) int { - for _, lbl := range task.Labels { - if lbl.Key == labelName { - value, err := strconv.Atoi(lbl.Value) - if err == nil { - if value <= maxValue { - return value - } - log.Warnf("The value %q for %q exceed the max authorized value %q, falling back to %v.", lbl.Value, labelName, maxValue, defaultValue) - } else { - log.Warnf("Unable to parse %q: %q, falling back to %v. %v", labelName, lbl.Value, defaultValue, err) - } - } - } - return defaultValue -} - -// Deprecated -func getSliceStringValueV1(task state.Task, labelName string) []string { - for _, lbl := range task.Labels { - if lbl.Key == labelName { - return label.SplitAndTrimString(lbl.Value, ",") - } - } - return nil -} - -// Deprecated -func getApplicationV1(task state.Task, apps []state.Task) (state.Task, error) { - for _, app := range apps { - if app.DiscoveryInfo.Name == task.DiscoveryInfo.Name { - return app, nil - } - } - return state.Task{}, fmt.Errorf("unable to get Mesos application from task %s", task.DiscoveryInfo.Name) -} diff --git a/provider/mesos/deprecated_config_test.go b/provider/mesos/deprecated_config_test.go deleted file mode 100644 index e2166097a..000000000 --- a/provider/mesos/deprecated_config_test.go +++ /dev/null @@ -1,432 +0,0 @@ -package mesos - -import ( - "testing" - - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/mesosphere/mesos-dns/records/state" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestBuildConfigurationV1(t *testing.T) { - p := &Provider{ - Domain: "mesos.localhost", - ExposedByDefault: true, - IPSources: "host", - } - - testCases := []struct { - desc string - tasks []state.Task - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - }{ - { - desc: "when no tasks", - tasks: []state.Task{}, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - }, - { - desc: "2 applications with 2 tasks", - tasks: []state.Task{ - // App 1 - aTask("ID1", - withIP("10.10.10.10"), - withInfo("name1", - withPorts(withPort("TCP", 80, "WEB"))), - withStatus(withHealthy(true), withState("TASK_RUNNING")), - ), - aTask("ID2", - withIP("10.10.10.11"), - withInfo("name1", - withPorts(withPort("TCP", 81, "WEB"))), - withStatus(withHealthy(true), withState("TASK_RUNNING")), - ), - // App 2 - aTask("ID3", - withIP("20.10.10.10"), - withInfo("name2", - withPorts(withPort("TCP", 80, "WEB"))), - withStatus(withHealthy(true), withState("TASK_RUNNING")), - ), - aTask("ID4", - withIP("20.10.10.11"), - withInfo("name2", - withPorts(withPort("TCP", 81, "WEB"))), - withStatus(withHealthy(true), withState("TASK_RUNNING")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-ID1": { - Backend: "backend-name1", - EntryPoints: []string{}, - PassHostHeader: true, - Routes: map[string]types.Route{ - "route-host-ID1": { - Rule: "Host:name1.mesos.localhost", - }, - }, - }, - "frontend-ID3": { - Backend: "backend-name2", - EntryPoints: []string{}, - PassHostHeader: true, - Routes: map[string]types.Route{ - "route-host-ID3": { - Rule: "Host:name2.mesos.localhost", - }, - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-name1": { - Servers: map[string]types.Server{ - "server-ID1": { - URL: "http://10.10.10.10:80", - Weight: label.DefaultWeight, - }, - "server-ID2": { - URL: "http://10.10.10.11:81", - Weight: label.DefaultWeight, - }, - }, - }, - "backend-name2": { - Servers: map[string]types.Server{ - "server-ID3": { - URL: "http://20.10.10.10:80", - Weight: label.DefaultWeight, - }, - "server-ID4": { - URL: "http://20.10.10.11:81", - Weight: label.DefaultWeight, - }, - }, - }, - }, - }, - { - desc: "with all labels", - tasks: []state.Task{ - aTask("ID1", - withLabel(label.TraefikPort, "666"), - withLabel(label.TraefikProtocol, "https"), - withLabel(label.TraefikWeight, "12"), - - withLabel(label.TraefikBackend, "foobar"), - - withLabel(label.TraefikBackendCircuitBreakerExpression, "NetworkErrorRatio() > 0.5"), - withLabel(label.TraefikBackendHealthCheckPath, "/health"), - withLabel(label.TraefikBackendHealthCheckPort, "880"), - withLabel(label.TraefikBackendHealthCheckInterval, "6"), - withLabel(label.TraefikBackendLoadBalancerMethod, "drr"), - withLabel(label.TraefikBackendLoadBalancerStickiness, "true"), - withLabel(label.TraefikBackendLoadBalancerStickinessCookieName, "chocolate"), - withLabel(label.TraefikBackendMaxConnAmount, "666"), - withLabel(label.TraefikBackendMaxConnExtractorFunc, "client.ip"), - withLabel(label.TraefikBackendBufferingMaxResponseBodyBytes, "10485760"), - withLabel(label.TraefikBackendBufferingMemResponseBodyBytes, "2097152"), - withLabel(label.TraefikBackendBufferingMaxRequestBodyBytes, "10485760"), - withLabel(label.TraefikBackendBufferingMemRequestBodyBytes, "2097152"), - withLabel(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"), - - withLabel(label.TraefikFrontendAuthBasic, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - withLabel(label.TraefikFrontendEntryPoints, "http,https"), - withLabel(label.TraefikFrontendPassHostHeader, "true"), - withLabel(label.TraefikFrontendPassTLSCert, "true"), - withLabel(label.TraefikFrontendPriority, "666"), - withLabel(label.TraefikFrontendRedirectEntryPoint, "https"), - withLabel(label.TraefikFrontendRedirectRegex, "nope"), - withLabel(label.TraefikFrontendRedirectReplacement, "nope"), - withLabel(label.TraefikFrontendRedirectPermanent, "true"), - withLabel(label.TraefikFrontendRule, "Host:traefik.io"), - withLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10"), - withLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true"), - - withLabel(label.TraefikFrontendRequestHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type:application/json; charset=utf-8"), - withLabel(label.TraefikFrontendResponseHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type:application/json; charset=utf-8"), - withLabel(label.TraefikFrontendSSLProxyHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type:application/json; charset=utf-8"), - withLabel(label.TraefikFrontendAllowedHosts, "foo,bar,bor"), - withLabel(label.TraefikFrontendHostsProxyHeaders, "foo,bar,bor"), - withLabel(label.TraefikFrontendSSLHost, "foo"), - withLabel(label.TraefikFrontendCustomFrameOptionsValue, "foo"), - withLabel(label.TraefikFrontendContentSecurityPolicy, "foo"), - withLabel(label.TraefikFrontendPublicKey, "foo"), - withLabel(label.TraefikFrontendReferrerPolicy, "foo"), - withLabel(label.TraefikFrontendCustomBrowserXSSValue, "foo"), - withLabel(label.TraefikFrontendSTSSeconds, "666"), - withLabel(label.TraefikFrontendSSLRedirect, "true"), - withLabel(label.TraefikFrontendSSLTemporaryRedirect, "true"), - withLabel(label.TraefikFrontendSTSIncludeSubdomains, "true"), - withLabel(label.TraefikFrontendSTSPreload, "true"), - withLabel(label.TraefikFrontendForceSTSHeader, "true"), - withLabel(label.TraefikFrontendFrameDeny, "true"), - withLabel(label.TraefikFrontendContentTypeNosniff, "true"), - withLabel(label.TraefikFrontendBrowserXSSFilter, "true"), - withLabel(label.TraefikFrontendIsDevelopment, "true"), - - withLabel(label.Prefix+label.BaseFrontendErrorPage+"foo."+label.SuffixErrorPageStatus, "404"), - withLabel(label.Prefix+label.BaseFrontendErrorPage+"foo."+label.SuffixErrorPageBackend, "foobar"), - withLabel(label.Prefix+label.BaseFrontendErrorPage+"foo."+label.SuffixErrorPageQuery, "foo_query"), - withLabel(label.Prefix+label.BaseFrontendErrorPage+"bar."+label.SuffixErrorPageStatus, "500,600"), - withLabel(label.Prefix+label.BaseFrontendErrorPage+"bar."+label.SuffixErrorPageBackend, "foobar"), - withLabel(label.Prefix+label.BaseFrontendErrorPage+"bar."+label.SuffixErrorPageQuery, "bar_query"), - - withLabel(label.TraefikFrontendRateLimitExtractorFunc, "client.ip"), - withLabel(label.Prefix+label.BaseFrontendRateLimit+"foo."+label.SuffixRateLimitPeriod, "6"), - withLabel(label.Prefix+label.BaseFrontendRateLimit+"foo."+label.SuffixRateLimitAverage, "12"), - withLabel(label.Prefix+label.BaseFrontendRateLimit+"foo."+label.SuffixRateLimitBurst, "18"), - withLabel(label.Prefix+label.BaseFrontendRateLimit+"bar."+label.SuffixRateLimitPeriod, "3"), - withLabel(label.Prefix+label.BaseFrontendRateLimit+"bar."+label.SuffixRateLimitAverage, "6"), - withLabel(label.Prefix+label.BaseFrontendRateLimit+"bar."+label.SuffixRateLimitBurst, "9"), - withIP("10.10.10.10"), - withInfo("name1", withPorts( - withPortTCP(80, "n"), - withPortTCP(666, "n"))), - withStatus(withHealthy(true), withState("TASK_RUNNING")), - ), - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-ID1": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backend-foobar", - Routes: map[string]types.Route{ - "route-host-ID1": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - Priority: 666, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-foobar": { - Servers: map[string]types.Server{ - "server-ID1": { - URL: "https://10.10.10.10:666", - Weight: 12, - }, - }, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actualConfig := p.buildConfigurationV1(test.tasks) - - require.NotNil(t, actualConfig) - assert.Equal(t, test.expectedBackends, actualConfig.Backends) - assert.Equal(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestTaskFilterV1(t *testing.T) { - testCases := []struct { - desc string - mesosTask state.Task - exposedByDefault bool - expected bool - }{ - { - desc: "no task", - mesosTask: state.Task{}, - exposedByDefault: true, - expected: false, - }, - { - desc: "task not healthy", - mesosTask: aTask("test", withStatus(withState("TASK_RUNNING"))), - exposedByDefault: true, - expected: false, - }, - { - desc: "exposedByDefault false and traefik.enable false", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "false"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: false, - expected: false, - }, - { - desc: "traefik.enable = true", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: false, - expected: true, - }, - { - desc: "exposedByDefault true and traefik.enable true", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: true, - }, - { - desc: "exposedByDefault true and traefik.enable false", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "false"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: false, - }, - { - desc: "traefik.portIndex and traefik.port both set", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPortIndex, "1"), - withLabel(label.TraefikEnable, "80"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: false, - }, - { - desc: "valid traefik.portIndex", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPortIndex, "1"), - withInfo("test", withPorts( - withPortTCP(80, "WEB"), - withPortTCP(443, "WEB HTTPS"), - )), - ), - exposedByDefault: true, - expected: true, - }, - { - desc: "default to first port index", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withInfo("test", withPorts( - withPortTCP(80, "WEB"), - withPortTCP(443, "WEB HTTPS"), - )), - ), - exposedByDefault: true, - expected: true, - }, - { - desc: "traefik.portIndex and discoveryPorts don't correspond", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPortIndex, "1"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: false, - }, - { - desc: "traefik.portIndex and discoveryPorts correspond", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPortIndex, "0"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: true, - }, - { - desc: "traefik.port is not an integer", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPort, "TRAEFIK"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: false, - }, - { - desc: "traefik.port is not the same as discovery.port", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPort, "443"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: false, - }, - { - desc: "traefik.port is the same as discovery.port", - mesosTask: aTask("test", - withDefaultStatus(), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPort, "80"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: true, - }, - { - desc: "healthy nil", - mesosTask: aTask("test", - withStatus( - withState("TASK_RUNNING"), - ), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPort, "80"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: true, - }, - { - desc: "healthy false", - mesosTask: aTask("test", - withStatus( - withState("TASK_RUNNING"), - withHealthy(false), - ), - withLabel(label.TraefikEnable, "true"), - withLabel(label.TraefikPort, "80"), - withInfo("test", withPorts(withPortTCP(80, "WEB"))), - ), - exposedByDefault: true, - expected: false, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := taskFilterV1(test.mesosTask, test.exposedByDefault) - ok := assert.Equal(t, test.expected, actual) - if !ok { - t.Logf("Statuses : %v", test.mesosTask.Statuses) - t.Logf("Label : %v", test.mesosTask.Labels) - t.Logf("DiscoveryInfo : %v", test.mesosTask.DiscoveryInfo) - t.Fatalf("Expected %v, got %v", test.expected, actual) - } - }) - } -} diff --git a/provider/rancher/config.go b/provider/rancher/config.go index 6b913333d..027624bca 100644 --- a/provider/rancher/config.go +++ b/provider/rancher/config.go @@ -14,7 +14,7 @@ import ( "github.com/containous/traefik/types" ) -func (p *Provider) buildConfigurationV2(services []rancherData) *types.Configuration { +func (p *Provider) buildConfiguration(services []rancherData) *types.Configuration { var RancherFuncMap = template.FuncMap{ "getLabelValue": label.GetStringValue, "getDomain": label.GetFuncString(label.TraefikDomain, p.Domain), diff --git a/provider/rancher/config_root.go b/provider/rancher/config_root.go deleted file mode 100644 index 203015470..000000000 --- a/provider/rancher/config_root.go +++ /dev/null @@ -1,12 +0,0 @@ -package rancher - -import ( - "github.com/containous/traefik/types" -) - -func (p *Provider) buildConfiguration(containersInspected []rancherData) *types.Configuration { - if p.TemplateVersion == 1 { - return p.buildConfigurationV1(containersInspected) - } - return p.buildConfigurationV2(containersInspected) -} diff --git a/provider/rancher/deprecated_config.go b/provider/rancher/deprecated_config.go deleted file mode 100644 index 2e04ca7b8..000000000 --- a/provider/rancher/deprecated_config.go +++ /dev/null @@ -1,233 +0,0 @@ -package rancher - -import ( - "strings" - "text/template" - - "github.com/BurntSushi/ty/fun" - "github.com/containous/traefik/log" - "github.com/containous/traefik/provider" - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" -) - -func (p *Provider) buildConfigurationV1(services []rancherData) *types.Configuration { - var RancherFuncMap = template.FuncMap{ - "getDomain": getFuncStringV1(label.TraefikDomain, p.Domain), - - // Backend functions - "getPort": getFuncStringV1(label.TraefikPort, ""), - "getProtocol": getFuncStringV1(label.TraefikProtocol, label.DefaultProtocol), - "getWeight": getFuncIntV1(label.TraefikWeight, label.DefaultWeight), - "hasCircuitBreakerLabel": hasFuncV1(label.TraefikBackendCircuitBreakerExpression), - "getCircuitBreakerExpression": getFuncStringV1(label.TraefikBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression), - "hasLoadBalancerLabel": hasLoadBalancerLabel, - "getLoadBalancerMethod": getFuncStringV1(label.TraefikBackendLoadBalancerMethod, label.DefaultBackendLoadBalancerMethod), - "hasMaxConnLabels": hasMaxConnLabels, - "getMaxConnAmount": getFuncInt64V1(label.TraefikBackendMaxConnAmount, 0), - "getMaxConnExtractorFunc": getFuncStringV1(label.TraefikBackendMaxConnExtractorFunc, label.DefaultBackendMaxconnExtractorFunc), - "getSticky": getStickyV1, - "hasStickinessLabel": hasFuncV1(label.TraefikBackendLoadBalancerStickiness), - "getStickinessCookieName": getFuncStringV1(label.TraefikBackendLoadBalancerStickinessCookieName, label.DefaultBackendLoadbalancerStickinessCookieName), - - // Frontend functions - "getBackend": getBackendNameV1, - "getFrontendRule": p.getFrontendRuleV1, - "getPriority": getFuncIntV1(label.TraefikFrontendPriority, label.DefaultFrontendPriority), - "getPassHostHeader": getFuncBoolV1(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), - "getEntryPoints": getFuncSliceStringV1(label.TraefikFrontendEntryPoints), - "getBasicAuth": getFuncSliceStringV1(label.TraefikFrontendAuthBasic), - "hasRedirect": hasRedirect, - "getRedirectEntryPoint": getRedirectEntryPoint, - "getRedirectRegex": getRedirectRegex, - "getRedirectReplacement": getRedirectReplacement, - } - - // filter services - filteredServices := fun.Filter(p.serviceFilterV1, services).([]rancherData) - - frontends := map[string]rancherData{} - backends := map[string]rancherData{} - - for _, service := range filteredServices { - frontendName := p.getFrontendNameV1(service) - frontends[frontendName] = service - backendName := getBackendNameV1(service) - backends[backendName] = service - } - - templateObjects := struct { - Frontends map[string]rancherData - Backends map[string]rancherData - Domain string - }{ - Frontends: frontends, - Backends: backends, - Domain: p.Domain, - } - - configuration, err := p.GetConfiguration("templates/rancher-v1.tmpl", RancherFuncMap, templateObjects) - if err != nil { - log.Error(err) - } - - return configuration -} - -// Deprecated -func (p *Provider) serviceFilterV1(service rancherData) bool { - if service.Labels[label.TraefikPort] == "" { - log.Debugf("Filtering service %s without traefik.port label", service.Name) - return false - } - - if !label.IsEnabled(service.Labels, p.ExposedByDefault) { - log.Debugf("Filtering disabled service %s", service.Name) - return false - } - - constraintTags := label.GetSliceStringValue(service.Labels, label.TraefikTags) - if ok, failingConstraint := p.MatchConstraints(constraintTags); !ok { - if failingConstraint != nil { - log.Debugf("Filtering service %s with constraint %s", service.Name, failingConstraint.String()) - } - return false - } - - // Only filter services by Health (HealthState) and State if EnableServiceHealthFilter is true - if p.EnableServiceHealthFilter { - - if service.Health != "" && service.Health != healthy && service.Health != updatingHealthy { - log.Debugf("Filtering service %s with healthState of %s", service.Name, service.Health) - return false - } - if service.State != "" && service.State != active && service.State != updatingActive && service.State != upgraded && service.State != upgrading { - log.Debugf("Filtering service %s with state of %s", service.Name, service.State) - return false - } - } - - return true -} - -// Deprecated -func (p *Provider) getFrontendRuleV1(service rancherData) string { - defaultRule := "Host:" + strings.ToLower(strings.Replace(service.Name, "/", ".", -1)) + "." + p.Domain - return label.GetStringValue(service.Labels, label.TraefikFrontendRule, defaultRule) -} - -// Deprecated -func (p *Provider) getFrontendNameV1(service rancherData) string { - return provider.Normalize(p.getFrontendRuleV1(service)) -} - -// Deprecated -func getBackendNameV1(service rancherData) string { - backend := label.GetStringValue(service.Labels, label.TraefikBackend, service.Name) - return provider.Normalize(backend) -} - -// TODO: Deprecated -// replaced by Stickiness -// Deprecated -func getStickyV1(service rancherData) bool { - if label.Has(service.Labels, label.TraefikBackendLoadBalancerSticky) { - log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness) - } - return label.GetBoolValue(service.Labels, label.TraefikBackendLoadBalancerSticky, false) -} - -// Deprecated -func hasLoadBalancerLabel(service rancherData) bool { - method := label.Has(service.Labels, label.TraefikBackendLoadBalancerMethod) - sticky := label.Has(service.Labels, label.TraefikBackendLoadBalancerSticky) - stickiness := label.Has(service.Labels, label.TraefikBackendLoadBalancerStickiness) - cookieName := label.Has(service.Labels, label.TraefikBackendLoadBalancerStickinessCookieName) - return method || sticky || stickiness || cookieName -} - -// Deprecated -func hasMaxConnLabels(service rancherData) bool { - mca := label.Has(service.Labels, label.TraefikBackendMaxConnAmount) - mcef := label.Has(service.Labels, label.TraefikBackendMaxConnExtractorFunc) - return mca && mcef -} - -func hasRedirect(service rancherData) bool { - value := label.GetStringValue(service.Labels, label.TraefikFrontendRedirectEntryPoint, "") - frep := len(value) > 0 - value = label.GetStringValue(service.Labels, label.TraefikFrontendRedirectRegex, "") - frrg := len(value) > 0 - value = label.GetStringValue(service.Labels, label.TraefikFrontendRedirectReplacement, "") - frrp := len(value) > 0 - - return frep || frrg && frrp -} - -func getRedirectEntryPoint(service rancherData) string { - value := label.GetStringValue(service.Labels, label.TraefikFrontendRedirectEntryPoint, "") - if len(value) == 0 { - return "" - } - return value -} - -func getRedirectRegex(service rancherData) string { - value := label.GetStringValue(service.Labels, label.TraefikFrontendRedirectRegex, "") - if len(value) == 0 { - return "" - } - return value -} - -func getRedirectReplacement(service rancherData) string { - value := label.GetStringValue(service.Labels, label.TraefikFrontendRedirectReplacement, "") - if len(value) == 0 { - return "" - } - return value -} - -// Label functions - -// Deprecated -func getFuncStringV1(labelName string, defaultValue string) func(service rancherData) string { - return func(service rancherData) string { - return label.GetStringValue(service.Labels, labelName, defaultValue) - } -} - -// Deprecated -func getFuncBoolV1(labelName string, defaultValue bool) func(service rancherData) bool { - return func(service rancherData) bool { - return label.GetBoolValue(service.Labels, labelName, defaultValue) - } -} - -// Deprecated -func getFuncIntV1(labelName string, defaultValue int) func(service rancherData) int { - return func(service rancherData) int { - return label.GetIntValue(service.Labels, labelName, defaultValue) - } -} - -// Deprecated -func getFuncInt64V1(labelName string, defaultValue int64) func(service rancherData) int64 { - return func(service rancherData) int64 { - return label.GetInt64Value(service.Labels, labelName, defaultValue) - } -} - -// Deprecated -func getFuncSliceStringV1(labelName string) func(service rancherData) []string { - return func(service rancherData) []string { - return label.GetSliceStringValue(service.Labels, labelName) - } -} - -// Deprecated -func hasFuncV1(labelName string) func(service rancherData) bool { - return func(service rancherData) bool { - return label.Has(service.Labels, labelName) - } -} diff --git a/provider/rancher/deprecated_config_test.go b/provider/rancher/deprecated_config_test.go deleted file mode 100644 index 6c92a889a..000000000 --- a/provider/rancher/deprecated_config_test.go +++ /dev/null @@ -1,503 +0,0 @@ -package rancher - -import ( - "testing" - - "github.com/containous/traefik/provider/label" - "github.com/containous/traefik/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestProviderBuildConfigurationV1(t *testing.T) { - provider := &Provider{ - Domain: "rancher.localhost", - ExposedByDefault: true, - } - - testCases := []struct { - desc string - services []rancherData - expectedFrontends map[string]*types.Frontend - expectedBackends map[string]*types.Backend - }{ - { - desc: "without services", - services: []rancherData{}, - expectedFrontends: map[string]*types.Frontend{}, - expectedBackends: map[string]*types.Backend{}, - }, - { - desc: "when all labels are set", - services: []rancherData{ - { - Labels: map[string]string{ - label.TraefikPort: "666", - label.TraefikProtocol: "https", - label.TraefikWeight: "12", - - label.TraefikBackend: "foobar", - - label.TraefikBackendCircuitBreakerExpression: "NetworkErrorRatio() > 0.5", - label.TraefikBackendLoadBalancerMethod: "drr", - label.TraefikBackendLoadBalancerSticky: "true", - label.TraefikBackendLoadBalancerStickiness: "true", - label.TraefikBackendLoadBalancerStickinessCookieName: "chocolate", - label.TraefikBackendMaxConnAmount: "666", - label.TraefikBackendMaxConnExtractorFunc: "client.ip", - - label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - label.TraefikFrontendEntryPoints: "http,https", - label.TraefikFrontendPassHostHeader: "true", - label.TraefikFrontendPriority: "666", - label.TraefikFrontendRedirectEntryPoint: "https", - label.TraefikFrontendRedirectRegex: "nope", - label.TraefikFrontendRedirectReplacement: "nope", - label.TraefikFrontendRule: "Host:traefik.io", - }, - Health: "healthy", - Containers: []string{"10.0.0.1", "10.0.0.2"}, - }, - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-Host-traefik-io": { - EntryPoints: []string{ - "http", - "https", - }, - Backend: "backend-foobar", - Routes: map[string]types.Route{ - "route-frontend-Host-traefik-io": { - Rule: "Host:traefik.io", - }, - }, - PassHostHeader: true, - Priority: 666, - BasicAuth: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - Redirect: &types.Redirect{ - EntryPoint: "https", - Regex: "nope", - Replacement: "nope", - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-foobar": { - Servers: map[string]types.Server{ - "server-0": { - URL: "https://10.0.0.1:666", - Weight: 12, - }, - "server-1": { - URL: "https://10.0.0.2:666", - Weight: 12, - }, - }, - CircuitBreaker: &types.CircuitBreaker{ - Expression: "NetworkErrorRatio() > 0.5", - }, - LoadBalancer: &types.LoadBalancer{ - Method: "drr", - Sticky: true, - Stickiness: &types.Stickiness{ - CookieName: "chocolate", - }, - }, - MaxConn: &types.MaxConn{ - Amount: 666, - ExtractorFunc: "client.ip", - }, - }, - }, - }, - { - desc: "with services", - services: []rancherData{ - { - Name: "test/service", - Labels: map[string]string{ - label.TraefikPort: "80", - label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - label.TraefikFrontendRedirectEntryPoint: "https", - }, - Health: "healthy", - Containers: []string{"127.0.0.1"}, - }, - }, - expectedFrontends: map[string]*types.Frontend{ - "frontend-Host-test-service-rancher-localhost": { - Backend: "backend-test-service", - PassHostHeader: true, - EntryPoints: []string{}, - BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"}, - Priority: 0, - Redirect: &types.Redirect{ - EntryPoint: "https", - }, - Routes: map[string]types.Route{ - "route-frontend-Host-test-service-rancher-localhost": { - Rule: "Host:test.service.rancher.localhost", - }, - }, - }, - }, - expectedBackends: map[string]*types.Backend{ - "backend-test-service": { - Servers: map[string]types.Server{ - "server-0": { - URL: "http://127.0.0.1:80", - Weight: label.DefaultWeight, - }, - }, - CircuitBreaker: nil, - }, - }, - }, - } - - for _, test := range testCases { - test := test - - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actualConfig := provider.buildConfigurationV1(test.services) - require.NotNil(t, actualConfig) - - assert.EqualValues(t, test.expectedBackends, actualConfig.Backends) - assert.EqualValues(t, test.expectedFrontends, actualConfig.Frontends) - }) - } -} - -func TestProviderServiceFilterV1(t *testing.T) { - provider := &Provider{ - Domain: "rancher.localhost", - EnableServiceHealthFilter: true, - } - - constraint, _ := types.NewConstraint("tag==ch*se") - provider.Constraints = types.Constraints{constraint} - - testCases := []struct { - desc string - service rancherData - expected bool - }{ - { - desc: "missing Port labels, don't respect constraint", - service: rancherData{ - Labels: map[string]string{ - label.TraefikEnable: "true", - }, - Health: "healthy", - State: "active", - }, - expected: false, - }, - { - desc: "don't respect constraint", - service: rancherData{ - Labels: map[string]string{ - label.TraefikPort: "80", - label.TraefikEnable: "false", - }, - Health: "healthy", - State: "active", - }, - expected: false, - }, - { - desc: "unhealthy", - service: rancherData{ - Labels: map[string]string{ - label.TraefikTags: "cheese", - label.TraefikPort: "80", - label.TraefikEnable: "true", - }, - Health: "unhealthy", - State: "active", - }, - expected: false, - }, - { - desc: "inactive", - service: rancherData{ - Labels: map[string]string{ - label.TraefikTags: "not-cheesy", - label.TraefikPort: "80", - label.TraefikEnable: "true", - }, - Health: "healthy", - State: "inactive", - }, - expected: false, - }, - { - desc: "healthy & active, tag: cheese", - service: rancherData{ - Labels: map[string]string{ - label.TraefikTags: "cheese", - label.TraefikPort: "80", - label.TraefikEnable: "true", - }, - Health: "healthy", - State: "active", - }, - expected: true, - }, - { - desc: "healthy & active, tag: chose", - service: rancherData{ - Labels: map[string]string{ - label.TraefikTags: "chose", - label.TraefikPort: "80", - label.TraefikEnable: "true", - }, - Health: "healthy", - State: "active", - }, - expected: true, - }, - { - desc: "healthy & upgraded", - service: rancherData{ - Labels: map[string]string{ - label.TraefikTags: "cheeeeese", - label.TraefikPort: "80", - label.TraefikEnable: "true", - }, - Health: "healthy", - State: "upgraded", - }, - expected: true, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := provider.serviceFilterV1(test.service) - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestContainerFilterV1(t *testing.T) { - testCases := []struct { - name string - healthState string - state string - expected bool - }{ - { - healthState: "unhealthy", - state: "running", - expected: false, - }, - { - healthState: "healthy", - state: "stopped", - expected: false, - }, - { - state: "stopped", - expected: false, - }, - { - healthState: "healthy", - state: "running", - expected: true, - }, - { - healthState: "updating-healthy", - state: "updating-running", - expected: true, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.healthState+" "+test.state, func(t *testing.T) { - t.Parallel() - - actual := containerFilter(test.name, test.healthState, test.state) - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestProviderGetFrontendNameV1(t *testing.T) { - provider := &Provider{Domain: "rancher.localhost"} - - testCases := []struct { - desc string - service rancherData - expected string - }{ - { - desc: "default", - service: rancherData{ - Name: "foo", - }, - expected: "Host-foo-rancher-localhost", - }, - { - desc: "with Headers label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikFrontendRule: "Headers:User-Agent,bat/0.1.0", - }, - }, - expected: "Headers-User-Agent-bat-0-1-0", - }, - { - desc: "with Host label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar", - }, - }, - expected: "Host-foo-bar", - }, - { - desc: "with Path label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikFrontendRule: "Path:/test", - }, - }, - expected: "Path-test", - }, - { - desc: "with PathPrefix label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikFrontendRule: "PathPrefix:/test2", - }, - }, - expected: "PathPrefix-test2", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := provider.getFrontendNameV1(test.service) - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestProviderGetFrontendRuleV1(t *testing.T) { - provider := &Provider{Domain: "rancher.localhost"} - - testCases := []struct { - desc string - service rancherData - expected string - }{ - { - desc: "host", - service: rancherData{ - Name: "foo", - }, - expected: "Host:foo.rancher.localhost", - }, - { - desc: "host with /", - service: rancherData{ - Name: "foo/bar", - }, - expected: "Host:foo.bar.rancher.localhost", - }, - { - desc: "with Host label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikFrontendRule: "Host:foo.bar.com", - }, - }, - expected: "Host:foo.bar.com", - }, - { - desc: "with Path label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikFrontendRule: "Path:/test", - }, - }, - expected: "Path:/test", - }, - { - desc: "with PathPrefix label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikFrontendRule: "PathPrefix:/test2", - }, - }, - expected: "PathPrefix:/test2", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := provider.getFrontendRule(test.service.Name, test.service.Labels) - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestGetBackendNameV1(t *testing.T) { - testCases := []struct { - desc string - service rancherData - expected string - }{ - { - desc: "without label", - service: rancherData{ - Name: "test-service", - }, - expected: "test-service", - }, - { - desc: "with label", - service: rancherData{ - Name: "test-service", - Labels: map[string]string{ - label.TraefikBackend: "foobar", - }, - }, - - expected: "foobar", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := getBackendNameV1(test.service) - assert.Equal(t, test.expected, actual) - }) - } -} diff --git a/templates/consul_catalog-v1.tmpl b/templates/consul_catalog-v1.tmpl deleted file mode 100644 index cb99198b4..000000000 --- a/templates/consul_catalog-v1.tmpl +++ /dev/null @@ -1,56 +0,0 @@ -[backends] -{{range $index, $node := .Nodes }} - [backends."backend-{{ getBackend $node }}".servers."{{ getBackendName $node $index }}"] - url = "{{ getAttribute "protocol" $node.Service.Tags "http" }}://{{ getBackendAddress $node }}:{{ $node.Service.Port }}" - {{ $weight := getAttribute "backend.weight" $node.Service.Tags "0" }} - {{with $weight }} - weight = {{ $weight }} - {{end}} -{{end}} - -{{range .Services }} - {{ $service := .ServiceName }} - - {{ $circuitBreaker := getAttribute "backend.circuitbreaker" .Attributes "" }} - {{with $circuitBreaker }} - [backends."backend-{{ $service }}".circuitbreaker] - expression = "{{ $circuitBreaker }}" - {{end}} - - [backends."backend-{{ $service }}".loadbalancer] - method = "{{ getAttribute "backend.loadbalancer" .Attributes "wrr" }}" - sticky = {{ getSticky .Attributes }} - {{if hasStickinessLabel .Attributes }} - [backends."backend-{{ $service }}".loadbalancer.stickiness] - cookieName = "{{ getStickinessCookieName .Attributes }}" - {{end}} - - {{if hasMaxconnAttributes .Attributes }} - [backends."backend-{{ $service }}".maxconn] - amount = {{ getAttribute "backend.maxconn.amount" .Attributes "" }} - extractorfunc = "{{ getAttribute "backend.maxconn.extractorfunc" .Attributes "" }}" - {{end}} - -{{end}} - -[frontends] -{{range .Services }} - [frontends."frontend-{{ .ServiceName }}"] - backend = "backend-{{ .ServiceName }}" - passHostHeader = {{ getAttribute "frontend.passHostHeader" .Attributes "true" }} - priority = {{ getAttribute "frontend.priority" .Attributes "0" }} - - {{ $entryPoints := getAttribute "frontend.entrypoints" .Attributes "" }} - {{with $entryPoints }} - entrypoints = [{{range getEntryPoints $entryPoints }} - "{{ . }}", - {{end}}] - {{end}} - - basicAuth = [{{range getBasicAuth .Attributes }} - "{{ . }}", - {{end}}] - - [frontends."frontend-{{ .ServiceName }}".routes."route-host-{{ .ServiceName }}"] - rule = "{{ getFrontendRule . }}" -{{end}} diff --git a/templates/docker-v1.tmpl b/templates/docker-v1.tmpl deleted file mode 100644 index 7163c19f7..000000000 --- a/templates/docker-v1.tmpl +++ /dev/null @@ -1,192 +0,0 @@ -{{$backendServers := .Servers}} - -[backends] -{{range $backendName, $backend := .Backends }} - - {{if hasCircuitBreakerLabel $backend }} - [backends."backend-{{ $backendName }}".circuitbreaker] - expression = "{{ getCircuitBreakerExpression $backend }}" - {{end}} - - {{if hasLoadBalancerLabel $backend }} - [backends."backend-{{ $backendName }}".loadbalancer] - method = "{{ getLoadBalancerMethod $backend }}" - sticky = {{ getSticky $backend }} - {{if hasStickinessLabel $backend }} - [backends."backend-{{ $backendName }}".loadbalancer.stickiness] - cookieName = "{{ getStickinessCookieName $backend }}" - {{end}} - {{end}} - - {{if hasMaxConnLabels $backend }} - [backends."backend-{{ $backendName }}".maxconn] - amount = {{ getMaxConnAmount $backend }} - extractorfunc = "{{ getMaxConnExtractorFunc $backend }}" - {{end}} - - {{ $servers := index $backendServers $backendName }} - {{range $serverName, $server := $servers }} - {{if hasServices $server }} - {{$services := getServiceNames $server }} - {{range $serviceIndex, $serviceName := $services }} - [backends."backend-{{ getServiceBackend $server $serviceName }}".servers."service-{{ $serverName }}"] - url = "{{ getServiceProtocol $server $serviceName }}://{{ getIPAddress $server }}:{{ getServicePort $server $serviceName }}" - weight = {{ getServiceWeight $server $serviceName }} - {{end}} - {{else}} - [backends."backend-{{ $backendName }}".servers."server-{{$server.Name | replace "/" "" | replace "." "-"}}"] - url = "{{ getProtocol $server }}://{{ getIPAddress $server }}:{{ getPort $server }}" - weight = {{ getWeight $server }} - {{end}} - {{end}} - -{{end}} - -[frontends] -{{range $frontend, $containers := .Frontends}} - {{$container := index $containers 0}} - - {{if hasServices $container }} - {{ $services := getServiceNames $container }} - {{range $serviceIndex, $serviceName := $services }} - [frontends."frontend-{{ getServiceBackend $container $serviceName }}"] - backend = "backend-{{ getServiceBackend $container $serviceName }}" - passHostHeader = {{ getServicePassHostHeader $container $serviceName }} - passTLSCert = {{ getServicePassTLSCert $container $serviceName }} - - {{if getWhitelistSourceRange $container }} - whitelistSourceRange = [{{range getWhitelistSourceRange $container }} - "{{.}}", - {{end}}] - {{end}} - - priority = {{ getServicePriority $container $serviceName }} - - entryPoints = [{{range getServiceEntryPoints $container $serviceName }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getServiceBasicAuth $container $serviceName }} - "{{.}}", - {{end}}] - - {{if hasServiceRedirect $container $serviceName }} - [frontends."frontend-{{ getServiceBackend $container $serviceName }}".redirect] - entryPoint = "{{ getServiceRedirectEntryPoint $container $serviceName }}" - regex = "{{ getServiceRedirectRegex $container $serviceName }}" - replacement = "{{ getServiceRedirectReplacement $container $serviceName }}" - {{end}} - - [frontends."frontend-{{ getServiceBackend $container $serviceName }}".routes."service-{{ $serviceName | replace "/" "" | replace "." "-" }}"] - rule = "{{ getServiceFrontendRule $container $serviceName }}" - {{end}} - {{else}} - [frontends."frontend-{{ $frontend }}"] - backend = "backend-{{ getBackend $container }}" - passHostHeader = {{ getPassHostHeader $container}} - passTLSCert = {{ getPassTLSCert $container }} - priority = {{ getPriority $container }} - - {{if getWhitelistSourceRange $container}} - whitelistSourceRange = [{{range getWhitelistSourceRange $container}} - "{{.}}", - {{end}}] - {{end}} - - entryPoints = [{{range getEntryPoints $container }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth $container }} - "{{.}}", - {{end}}] - - {{if hasRedirect $container}} - [frontends."frontend-{{$frontend}}".redirect] - entryPoint = "{{getRedirectEntryPoint $container}}" - regex = "{{getRedirectRegex $container}}" - replacement = "{{getRedirectReplacement $container}}" - {{end}} - - {{if hasHeaders $container }} - [frontends."frontend-{{ $frontend }}".headers] - {{if hasSSLRedirectHeaders $container}} - SSLRedirect = {{getSSLRedirectHeaders $container}} - {{end}} - {{if hasSSLTemporaryRedirectHeaders $container}} - SSLTemporaryRedirect = {{getSSLTemporaryRedirectHeaders $container}} - {{end}} - {{if hasSSLHostHeaders $container}} - SSLHost = "{{getSSLHostHeaders $container}}" - {{end}} - {{if hasSTSSecondsHeaders $container}} - STSSeconds = {{getSTSSecondsHeaders $container}} - {{end}} - {{if hasSTSIncludeSubdomainsHeaders $container}} - STSIncludeSubdomains = {{getSTSIncludeSubdomainsHeaders $container}} - {{end}} - {{if hasSTSPreloadHeaders $container}} - STSPreload = {{getSTSPreloadHeaders $container}} - {{end}} - {{if hasForceSTSHeaderHeaders $container}} - ForceSTSHeader = {{getForceSTSHeaderHeaders $container}} - {{end}} - {{if hasFrameDenyHeaders $container}} - FrameDeny = {{getFrameDenyHeaders $container}} - {{end}} - {{if hasCustomFrameOptionsValueHeaders $container}} - CustomFrameOptionsValue = "{{getCustomFrameOptionsValueHeaders $container}}" - {{end}} - {{if hasContentTypeNosniffHeaders $container}} - ContentTypeNosniff = {{getContentTypeNosniffHeaders $container}} - {{end}} - {{if hasBrowserXSSFilterHeaders $container}} - BrowserXSSFilter = {{getBrowserXSSFilterHeaders $container}} - {{end}} - {{if hasContentSecurityPolicyHeaders $container}} - ContentSecurityPolicy = "{{getContentSecurityPolicyHeaders $container}}" - {{end}} - {{if hasPublicKeyHeaders $container}} - PublicKey = "{{getPublicKeyHeaders $container}}" - {{end}} - {{if hasReferrerPolicyHeaders $container}} - ReferrerPolicy = "{{getReferrerPolicyHeaders $container}}" - {{end}} - {{if hasIsDevelopmentHeaders $container}} - IsDevelopment = {{getIsDevelopmentHeaders $container}} - {{end}} - {{if hasAllowedHostsHeaders $container}} - AllowedHosts = [{{range getAllowedHostsHeaders $container}} - "{{.}}", - {{end}}] - {{end}} - {{if hasHostsProxyHeaders $container}} - HostsProxyHeaders = [{{range getHostsProxyHeaders $container}} - "{{.}}", - {{end}}] - {{end}} - {{if hasRequestHeaders $container}} - [frontends."frontend-{{$frontend}}".headers.customrequestheaders] - {{range $k, $v := getRequestHeaders $container}} - {{$k}} = "{{$v}}" - {{end}} - {{end}} - {{if hasResponseHeaders $container}} - [frontends."frontend-{{$frontend}}".headers.customresponseheaders] - {{range $k, $v := getResponseHeaders $container}} - {{$k}} = "{{$v}}" - {{end}} - {{end}} - {{if hasSSLProxyHeaders $container}} - [frontends."frontend-{{$frontend}}".headers.SSLProxyHeaders] - {{range $k, $v := getSSLProxyHeaders $container}} - {{$k}} = "{{$v}}" - {{end}} - {{end}} - {{end}} - - [frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"] - rule = "{{getFrontendRule $container}}" - {{end}} - -{{end}} diff --git a/templates/ecs-v1.tmpl b/templates/ecs-v1.tmpl deleted file mode 100644 index edb16643b..000000000 --- a/templates/ecs-v1.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -[backends] -{{range $serviceName, $instances := .Services }} - [backends."backend-{{ $serviceName }}".loadBalancer] - method = "{{ getLoadBalancerMethod $instances }}" - sticky = {{ getLoadBalancerSticky $instances }} - - {{if hasStickinessLabel $instances }} - [backends."backend-{{ $serviceName }}".loadBalancer.stickiness] - cookieName = "{{ getStickinessCookieName $instances }}" - {{end}} - - {{ if hasHealthCheckLabels $instances }} - [backends."backend-{{ $serviceName }}".healthCheck] - path = "{{ getHealthCheckPath $instances }}" - interval = "{{ getHealthCheckInterval $instances }}" - {{end}} - - {{range $index, $i := $instances }} - [backends."backend-{{ $serviceName }}".servers."server-{{ $i.Name }}{{ $i.ID }}"] - url = "{{ getProtocol $i }}://{{ getHost $i }}:{{ getPort $i }}" - weight = {{ getWeight $i }} - {{end}} -{{end}} - -[frontends] -{{range $serviceName, $instances := .Services}} -{{range filterFrontends $instances }} - [frontends."frontend-{{ $serviceName }}"] - backend = "backend-{{ $serviceName }}" - passHostHeader = {{ getPassHostHeader . }} - priority = {{ getPriority . }} - - entryPoints = [{{range getEntryPoints . }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth . }} - "{{.}}", - {{end}}] - - [frontends."frontend-{{ $serviceName }}".routes."route-frontend-{{ $serviceName }}"] - rule = "{{getFrontendRule .}}" -{{end}} -{{end}} \ No newline at end of file diff --git a/templates/marathon-v1.tmpl b/templates/marathon-v1.tmpl deleted file mode 100644 index 2abd83de5..000000000 --- a/templates/marathon-v1.tmpl +++ /dev/null @@ -1,68 +0,0 @@ -{{$apps := .Applications}} - -{{range $app := $apps }} -{{range $task := $app.Tasks }} -{{range $serviceIndex, $serviceName := getServiceNames $app }} - [backends."{{ getBackend $app $serviceName }}".servers."server-{{ $task.ID | replace "." "-"}}{{getServiceNameSuffix $serviceName }}"] - url = "{{ getProtocol $app $serviceName }}://{{ getBackendServer $task $app }}:{{ getPort $task $app $serviceName }}" - weight = {{ getWeight $app $serviceName }} -{{end}} -{{end}} -{{end}} - -{{range $app := $apps }} -{{range $serviceIndex, $serviceName := getServiceNames $app }} - -[backends."{{ getBackend $app $serviceName }}"] - {{if hasMaxConnLabels $app }} - [backends."{{ getBackend $app $serviceName }}".maxConn] - amount = {{ getMaxConnAmount $app }} - extractorFunc = "{{ getMaxConnExtractorFunc $app }}" - {{end}} - - {{if hasLoadBalancerLabels $app }} - [backends."{{ getBackend $app $serviceName }}".loadBalancer] - method = "{{ getLoadBalancerMethod $app }}" - sticky = {{ getSticky $app }} - {{if hasStickinessLabel $app }} - [backends."{{ getBackend $app $serviceName }}".loadBalancer.stickiness] - cookieName = "{{ getStickinessCookieName $app }}" - {{end}} - {{end}} - - {{if hasCircuitBreakerLabels $app }} - [backends."{{ getBackend $app $serviceName }}".circuitBreaker] - expression = "{{ getCircuitBreakerExpression $app }}" - {{end}} - - {{if hasHealthCheckLabels $app }} - [backends."{{ getBackend $app $serviceName }}".healthCheck] - path = "{{ getHealthCheckPath $app }}" - interval = "{{ getHealthCheckInterval $app }}" - {{end}} - -{{end}} -{{end}} - -[frontends] -{{range $app := $apps }} -{{range $serviceIndex, $serviceName := getServiceNames . }} - - [frontends."{{ getFrontendName $app $serviceName | normalize }}"] - backend = "{{ getBackend $app $serviceName }}" - passHostHeader = {{ getPassHostHeader $app $serviceName }} - priority = {{ getPriority $app $serviceName }} - - entryPoints = [{{range getEntryPoints $app $serviceName }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth $app $serviceName }} - "{{.}}", - {{end}}] - - [frontends."{{ getFrontendName $app $serviceName | normalize }}".routes."route-host{{ $app.ID | replace "/" "-" }}{{ getServiceNameSuffix $serviceName }}"] - rule = "{{ getFrontendRule $app $serviceName }}" - -{{end}} -{{end}} diff --git a/templates/mesos-v1.tmpl b/templates/mesos-v1.tmpl deleted file mode 100644 index 3ec2990d9..000000000 --- a/templates/mesos-v1.tmpl +++ /dev/null @@ -1,27 +0,0 @@ -{{$apps := .Applications}} - -[backends] -{{range .Tasks}} - - [backends."backend-{{ getBackend . $apps }}".servers."server-{{ getID . }}"] - url = "{{ getProtocol . $apps }}://{{ getHost . }}:{{ getPort . $apps }}" - weight = {{ getWeight . $apps }} - -{{end}} - -[frontends] -{{range .Applications}} - - [frontends."frontend-{{getFrontEndName . }}"] - backend = "backend-{{ getFrontendBackend . }}" - passHostHeader = {{ getPassHostHeader . }} - priority = {{ getPriority . }} - - entryPoints = [{{range getEntryPoints . }} - "{{.}}", - {{end}}] - - [frontends."frontend-{{ getFrontEndName . }}".routes."route-host-{{ getFrontEndName . }}"] - rule = "{{ getFrontendRule . }}" - -{{end}} diff --git a/templates/rancher-v1.tmpl b/templates/rancher-v1.tmpl deleted file mode 100644 index b1da1d472..000000000 --- a/templates/rancher-v1.tmpl +++ /dev/null @@ -1,58 +0,0 @@ -{{$backendServers := .Backends}} - -[backends] -{{range $backendName, $backend := .Backends }} - {{if hasCircuitBreakerLabel $backend }} - [backends."backend-{{ $backendName }}".circuitBreaker] - expression = "{{ getCircuitBreakerExpression $backend }}" - {{end}} - - {{if hasLoadBalancerLabel $backend }} - [backends."backend-{{ $backendName }}".loadBalancer] - method = "{{ getLoadBalancerMethod $backend }}" - sticky = {{ getSticky $backend }} - {{if hasStickinessLabel $backend }} - [backends."backend-{{ $backendName }}".loadBalancer.stickiness] - cookieName = "{{ getStickinessCookieName $backend }}" - {{end}} - {{end}} - - {{if hasMaxConnLabels $backend }} - [backends."backend-{{ $backendName }}".maxConn] - amount = {{ getMaxConnAmount $backend }} - extractorFunc = "{{ getMaxConnExtractorFunc $backend }}" - {{end}} - - {{range $index, $ip := $backend.Containers }} - [backends."backend-{{ $backendName }}".servers."server-{{ $index }}"] - url = "{{ getProtocol $backend }}://{{ $ip }}:{{ getPort $backend }}" - weight = {{ getWeight $backend }} - {{end}} - -{{end}} - -[frontends] -{{range $frontendName, $service := .Frontends }} - [frontends."frontend-{{ $frontendName }}"] - backend = "backend-{{ getBackend $service }}" - passHostHeader = {{ getPassHostHeader $service }} - priority = {{ getPriority $service }} - - entryPoints = [{{range getEntryPoints $service }} - "{{.}}", - {{end}}] - - basicAuth = [{{range getBasicAuth $service }} - "{{.}}", - {{end}}] - - {{if hasRedirect $service }} - [frontends."frontend-{{ $frontendName }}".redirect] - entryPoint = "{{ getRedirectEntryPoint $service }}" - regex = "{{ getRedirectRegex $service }}" - replacement = "{{ getRedirectReplacement $service }}" - {{end}} - - [frontends."frontend-{{ $frontendName }}".routes."route-frontend-{{ $frontendName }}"] - rule = "{{ getFrontendRule $service }}" -{{end}}