traefik/pkg/provider/consulcatalog/config_test.go
2024-03-12 12:08:03 +01:00

3899 lines
108 KiB
Go

package consulcatalog
import (
"context"
"fmt"
"testing"
"time"
"github.com/hashicorp/consul/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/tls"
"github.com/traefik/traefik/v3/pkg/types"
)
func Int(v int) *int { return &v }
func Bool(v bool) *bool { return &v }
func TestDefaultRule(t *testing.T) {
testCases := []struct {
desc string
items []itemData
defaultRule string
expected *dynamic.Configuration
}{
{
desc: "default rule with no variable",
items: []itemData{
{
ID: "id",
Node: "Node1",
Name: "Test",
Address: "127.0.0.1",
Port: "80",
Labels: nil,
Status: api.HealthPassing,
},
},
defaultRule: "Host(`foo.bar`)",
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "default rule with label",
items: []itemData{
{
ID: "id",
Node: "Node1",
Name: "Test",
Address: "127.0.0.1",
Port: "80",
Labels: map[string]string{
"traefik.domain": "foo.bar",
},
Status: api.HealthPassing,
},
},
defaultRule: `Host("{{ .Name }}.{{ index .Labels "traefik.domain" }}")`,
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: `Host("Test.foo.bar")`,
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "invalid rule",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
defaultRule: `Host("{{ .Toto }}")`,
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "undefined rule",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
defaultRule: ``,
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "default template rule",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
defaultRule: defaultTemplateRule,
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
var config Configuration
config.SetDefaults()
config.DefaultRule = test.defaultRule
p := Provider{
Configuration: config,
}
err := p.Init()
require.NoError(t, err)
for i := range len(test.items) {
var err error
test.items[i].ExtraConf, err = p.getExtraConf(test.items[i].Labels)
require.NoError(t, err)
}
configuration := p.buildConfiguration(context.Background(), test.items, nil)
assert.Equal(t, test.expected, configuration)
})
}
}
func Test_buildConfiguration(t *testing.T) {
testCases := []struct {
desc string
items []itemData
constraints string
ConnectAware bool
expected *dynamic.Configuration
}{
{
desc: "one container no label",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "dev/Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one connect container",
ConnectAware: true,
items: []itemData{
{
ID: "Test",
Node: "Node1",
Datacenter: "dc1",
Name: "dev/Test",
Namespace: "ns",
Address: "127.0.0.1",
Port: "443",
Status: api.HealthPassing,
Labels: map[string]string{
"traefik.consulcatalog.connect": "true",
},
Tags: nil,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "https://127.0.0.1:443",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "tls-ns-dc1-dev-Test",
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{
"tls-ns-dc1-dev-Test": {
ServerName: "ns-dc1-dev/Test",
InsecureSkipVerify: true,
RootCAs: []types.FileOrContent{
"root",
},
Certificates: []tls.Certificate{
{
CertFile: "cert",
KeyFile: "key",
},
},
PeerCertURI: "spiffe:///ns/ns/dc/dc1/svc/dev/Test",
},
},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two connect containers on same service",
ConnectAware: true,
items: []itemData{
{
ID: "Test1",
Node: "Node1",
Datacenter: "dc1",
Name: "dev/Test",
Namespace: "ns",
Address: "127.0.0.1",
Port: "443",
Status: api.HealthPassing,
Labels: map[string]string{
"traefik.consulcatalog.connect": "true",
},
Tags: nil,
},
{
ID: "Test2",
Node: "Node2",
Datacenter: "dc1",
Name: "dev/Test",
Namespace: "ns",
Address: "127.0.0.2",
Port: "444",
Status: api.HealthPassing,
Labels: map[string]string{
"traefik.consulcatalog.connect": "true",
},
Tags: nil,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "https://127.0.0.1:443",
},
{
URL: "https://127.0.0.2:444",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "tls-ns-dc1-dev-Test",
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{
"tls-ns-dc1-dev-Test": {
ServerName: "ns-dc1-dev/Test",
InsecureSkipVerify: true,
RootCAs: []types.FileOrContent{
"root",
},
Certificates: []tls.Certificate{
{
CertFile: "cert",
KeyFile: "key",
},
},
PeerCertURI: "spiffe:///ns/ns/dc/dc1/svc/dev/Test",
},
},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers no label",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "Test2",
Node: "Node1",
Name: "Test2",
Labels: map[string]string{},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`Test2.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with same service name no label",
items: []itemData{
{
ID: "1",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with same service name & id no label on same node",
items: []itemData{
{
ID: "1",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "1",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with same service name & id no label on different nodes",
items: []itemData{
{
ID: "1",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "1",
Node: "Node2",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with label (not on server)",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with labels",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.service": "Service1",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Router1": {
Service: "Service1",
Rule: "Host(`foo.com`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with rule label",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
Routers: map[string]*dynamic.Router{
"Router1": {
Service: "Test",
Rule: "Host(`foo.com`)",
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with rule label and one service",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Router1": {
Service: "Service1",
Rule: "Host(`foo.com`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with rule label and two services",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
"traefik.http.services.Service2.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with same service name and different passhostheader",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "false",
}, Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "three containers with same service name and different passhostheader",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "false",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "3",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with same service name and same LB methods",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with InFlightReq in label (default value)",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
Middlewares: map[string]*dynamic.Middleware{
"Middleware1": {
InFlightReq: &dynamic.InFlightReq{
Amount: 42,
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two services with two identical middlewares",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
}, Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
"Middleware1": {
InFlightReq: &dynamic.InFlightReq{
Amount: 42,
},
},
},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with two different middlewares with same name",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "41",
}, Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "three containers with different middlewares with same name",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "41",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "3",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "40",
},
Address: "127.0.0.3",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
{
URL: "http://127.0.0.3:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with two different routers with same name",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`bar.com`)",
}, Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "three containers with different routers with same name",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`bar.com`)",
}, Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "3",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foobar.com`)",
},
Address: "127.0.0.3",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
{
URL: "http://127.0.0.3:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two containers with two identical routers",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Router1": {
Service: "Test",
Rule: "Host(`foo.com`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with bad label",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.wrong.label": "42",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with label port",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.LoadBalancer.server.scheme": "h2c",
"traefik.http.services.Service1.LoadBalancer.server.port": "8080",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "h2c://127.0.0.1:8080",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with label port on two services",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Service1.LoadBalancer.server.port": "",
"traefik.http.services.Service2.LoadBalancer.server.port": "8080",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:8080",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container without port",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.2",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container without port with middleware",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
Address: "127.0.0.2",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with traefik.enable false",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.enable": "false",
},
Address: "127.0.0.1",
Port: "80",
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container not healthy",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "Test",
Labels: map[string]string{},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthCritical,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with non matching constraints",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tags": "foo",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
constraints: `Tag("traefik.tags=bar")`,
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with matching constraints",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tags": "foo",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
constraints: `Tag("traefik.tags=foo")`,
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "Middlewares used in router",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.middlewares.Middleware1.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
"traefik.http.routers.Test.middlewares": "Middleware1",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
Middlewares: []string{"Middleware1"},
},
},
Middlewares: map[string]*dynamic.Middleware{
"Middleware1": {
BasicAuth: &dynamic.BasicAuth{
Users: []string{
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
},
},
},
},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "Middlewares used in TCP router",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.routers.Test.rule": "HostSNI(`foo.bar`)",
"traefik.tcp.middlewares.Middleware1.ipallowlist.sourcerange": "foobar, fiibar",
"traefik.tcp.routers.Test.middlewares": "Middleware1",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{
"Test": {
Service: "Test",
Rule: "HostSNI(`foo.bar`)",
Middlewares: []string{"Middleware1"},
},
},
Middlewares: map[string]*dynamic.TCPMiddleware{
"Middleware1": {
IPAllowList: &dynamic.TCPIPAllowList{
SourceRange: []string{"foobar", "fiibar"},
},
},
},
Services: map[string]*dynamic.TCPService{
"Test": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:80",
},
},
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "tcp with label",
ConnectAware: true,
items: []itemData{
{
ID: "Test",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
"traefik.tcp.routers.foo.tls": "true",
"traefik.consulcatalog.connect": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{
"foo": {
Service: "Test",
Rule: "HostSNI(`foo.bar`)",
TLS: &dynamic.RouterTCPTLSConfig{},
},
},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"Test": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:80",
TLS: true,
},
},
ServersTransport: "tls-ns-dc1-Test",
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{
"tls-ns-dc1-Test": {
TLS: &dynamic.TLSClientConfig{
ServerName: "ns-dc1-Test",
InsecureSkipVerify: true,
RootCAs: []types.FileOrContent{
"root",
},
Certificates: []tls.Certificate{
{
CertFile: "cert",
KeyFile: "key",
},
},
PeerCertURI: "spiffe:///ns/ns/dc/dc1/svc/Test",
},
},
},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "udp with label",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.udp.routers.foo.entrypoints": "mydns",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{
"foo": {
Service: "Test",
EntryPoints: []string{"mydns"},
},
},
Services: map[string]*dynamic.UDPService{
"Test": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{
Address: "127.0.0.1:80",
},
},
},
},
},
},
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "tcp with label without rule",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.routers.foo.tls": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"Test": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:80",
},
},
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "tcp with label and port",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
"traefik.tcp.routers.foo.tls.options": "foo",
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{
"foo": {
Service: "foo",
Rule: "HostSNI(`foo.bar`)",
TLS: &dynamic.RouterTCPTLSConfig{
Options: "foo",
},
},
},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"foo": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:8080",
},
},
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "udp with label and port",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.udp.routers.foo.entrypoints": "mydns",
"traefik.udp.services.foo.loadbalancer.server.port": "80",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{
"foo": {
Service: "foo",
EntryPoints: []string{"mydns"},
},
},
Services: map[string]*dynamic.UDPService{
"foo": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{
Address: "127.0.0.1:80",
},
},
},
},
},
},
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "tcp with label and port and http service",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
"traefik.tcp.routers.foo.tls": "true",
"traefik.tcp.services.foo.loadbalancer.server.port": "80",
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
"traefik.tcp.routers.foo.tls": "true",
"traefik.tcp.services.foo.loadbalancer.server.port": "80",
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{
"foo": {
Service: "foo",
Rule: "HostSNI(`foo.bar`)",
TLS: &dynamic.RouterTCPTLSConfig{},
},
},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"foo": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:80",
},
{
Address: "127.0.0.2:80",
},
},
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "udp with label and port and http service",
items: []itemData{
{
ID: "1",
Name: "Test",
Labels: map[string]string{
"traefik.udp.routers.foo.entrypoints": "mydns",
"traefik.udp.services.foo.loadbalancer.server.port": "80",
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Name: "Test",
Labels: map[string]string{
"traefik.udp.routers.foo.entrypoints": "mydns",
"traefik.udp.services.foo.loadbalancer.server.port": "80",
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{
"foo": {
Service: "foo",
EntryPoints: []string{"mydns"},
},
},
Services: map[string]*dynamic.UDPService{
"foo": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{
Address: "127.0.0.1:80",
},
{
Address: "127.0.0.2:80",
},
},
},
},
},
},
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
{
URL: "http://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "tcp with label for tcp service",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.services.foo.loadbalancer.server.port": "80",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"foo": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:80",
},
},
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "udp with label for tcp service",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.udp.services.foo.loadbalancer.server.port": "80",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{
"foo": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{
Address: "127.0.0.1:80",
},
},
},
},
},
},
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
// TODO: replace or delete?
desc: "tcp with label for tcp service, with termination delay",
items: []itemData{
{
ID: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.services.foo.loadbalancer.server.port": "80",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"foo": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:80",
},
},
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two HTTP service instances with one canary",
ConnectAware: true,
items: []itemData{
{
ID: "1",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.consulcatalog.connect": "true",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.consulcatalog.connect": "true",
"traefik.consulcatalog.canary": "true",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
"Test-97077516270503695": {
Service: "Test-97077516270503695",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "https://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "tls-ns-dc1-Test",
},
},
"Test-97077516270503695": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "https://127.0.0.2:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "tls-ns-dc1-Test",
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{
"tls-ns-dc1-Test": {
ServerName: "ns-dc1-Test",
InsecureSkipVerify: true,
RootCAs: []types.FileOrContent{
"root",
},
Certificates: []tls.Certificate{
{
CertFile: "cert",
KeyFile: "key",
},
},
PeerCertURI: "spiffe:///ns/ns/dc/dc1/svc/Test",
},
},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two TCP service instances with one canary",
ConnectAware: true,
items: []itemData{
{
ID: "1",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.tcp.routers.test.rule": "HostSNI(`foobar`)",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.consulcatalog.canary": "true",
"traefik.tcp.routers.test-canary.rule": "HostSNI(`canary.foobar`)",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{
"test": {
Service: "Test",
Rule: "HostSNI(`foobar`)",
},
"test-canary": {
Service: "Test-17573747155436217342",
Rule: "HostSNI(`canary.foobar`)",
},
},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"Test": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{Address: "127.0.0.1:80"},
},
},
},
"Test-17573747155436217342": {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{Address: "127.0.0.2:80"},
},
},
},
},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "two UDP service instances with one canary",
ConnectAware: true,
items: []itemData{
{
ID: "1",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.udp.routers.test.entrypoints": "udp",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
{
ID: "2",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.consulcatalog.canary": "true",
"traefik.udp.routers.test-canary.entrypoints": "udp",
},
Address: "127.0.0.2",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{
"test": {
EntryPoints: []string{"udp"},
Service: "Test",
},
"test-canary": {
EntryPoints: []string{"udp"},
Service: "Test-12825244908842506376",
},
},
Services: map[string]*dynamic.UDPService{
"Test": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{Address: "127.0.0.1:80"},
},
},
},
"Test-12825244908842506376": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{Address: "127.0.0.2:80"},
},
},
},
},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "UDP service with labels only",
ConnectAware: true,
items: []itemData{
{
ID: "1",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.udp.routers.test-udp-label.service": "test-udp-label-service",
"traefik.udp.routers.test-udp-label.entryPoints": "udp",
"traefik.udp.services.test-udp-label-service.loadBalancer.server.port": "21116",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{
"test-udp-label": {
EntryPoints: []string{"udp"},
Service: "test-udp-label-service",
},
},
Services: map[string]*dynamic.UDPService{
"test-udp-label-service": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{Address: "127.0.0.1:21116"},
},
},
},
},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
desc: "one container with default generated certificate labels",
items: []itemData{
{
ID: "Test",
Node: "Node1",
Name: "dev/Test",
Labels: map[string]string{
"traefik.tls.stores.default.defaultgeneratedcert.resolver": "foobar",
"traefik.tls.stores.default.defaultgeneratedcert.domain.main": "foobar",
"traefik.tls.stores.default.defaultgeneratedcert.domain.sans": "foobar, fiibar",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{
"default": {
DefaultGeneratedCert: &tls.GeneratedCert{
Resolver: "foobar",
Domain: &types.Domain{
Main: "foobar",
SANs: []string{"foobar", "fiibar"},
},
},
},
},
},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
var config Configuration
config.SetDefaults()
config.DefaultRule = "Host(`{{ normalize .Name }}.traefik.wtf`)"
config.ConnectAware = test.ConnectAware
config.Constraints = test.constraints
p := Provider{
Configuration: config,
}
err := p.Init()
require.NoError(t, err)
for i := range len(test.items) {
var err error
test.items[i].ExtraConf, err = p.getExtraConf(test.items[i].Labels)
require.NoError(t, err)
var tags []string
for k, v := range test.items[i].Labels {
tags = append(tags, fmt.Sprintf("%s=%s", k, v))
}
test.items[i].Tags = tags
}
configuration := p.buildConfiguration(context.Background(), test.items, &connectCert{
root: []string{"root"},
leaf: keyPair{
cert: "cert",
key: "key",
},
})
assert.Equal(t, test.expected, configuration)
})
}
}
func TestNamespaces(t *testing.T) {
testCases := []struct {
desc string
namespaces []string
expectedNamespaces []string
}{
{
desc: "no defined namespaces",
expectedNamespaces: []string{""},
},
{
desc: "use of 1 defined namespaces",
namespaces: []string{"test-ns"},
expectedNamespaces: []string{"test-ns"},
},
{
desc: "use of multiple defined namespaces",
namespaces: []string{"test-ns1", "test-ns2", "test-ns3", "test-ns4"},
expectedNamespaces: []string{"test-ns1", "test-ns2", "test-ns3", "test-ns4"},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
pb := &ProviderBuilder{
Namespaces: test.namespaces,
}
assert.Equal(t, test.expectedNamespaces, extractNSFromProvider(pb.BuildProviders()))
})
}
}
func extractNSFromProvider(providers []*Provider) []string {
res := make([]string, len(providers))
for i, p := range providers {
res[i] = p.namespace
}
return res
}
func TestFilterHealthStatuses(t *testing.T) {
testCases := []struct {
desc string
items []itemData
strictChecks []string
expected *dynamic.Configuration
}{
{
// No value passed in here, we assume the default of ["passing", "warning"]
desc: "test default strict checks",
strictChecks: defaultStrictChecks(),
items: []itemData{
{
ID: "id",
Node: "Node1",
Name: "Test1",
Address: "127.0.0.1",
Port: "80",
Labels: nil,
Status: api.HealthPassing,
},
{
ID: "id",
Node: "Node2",
Name: "Test2",
Address: "127.0.0.1",
Port: "81",
Labels: nil,
Status: api.HealthWarning,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test1": {
Service: "Test1",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:81",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
// The item's health status is not included in the default checks, do not expect any containers
desc: "test status not included",
strictChecks: defaultStrictChecks(),
items: []itemData{
{
ID: "id",
Node: "Node1",
Name: "Test",
Address: "127.0.0.1",
Port: "80",
Labels: nil,
Status: api.HealthCritical,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
// Allow only "warning" status containers to be included
desc: "test only include warning",
strictChecks: []string{api.HealthWarning},
items: []itemData{
{
ID: "id",
Node: "Node1",
Name: "Test1",
Address: "127.0.0.1",
Port: "80",
Labels: nil,
Status: api.HealthPassing,
},
{
ID: "id2",
Node: "Node2",
Name: "Test2",
Address: "127.0.0.1",
Port: "81",
Labels: nil,
Status: api.HealthWarning,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test2": {
Service: "Test2",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:81",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
// Reject "critical" health status
desc: "test critical status not included",
strictChecks: defaultStrictChecks(),
items: []itemData{
{
ID: "id",
Node: "Node1",
Name: "Test1",
Address: "127.0.0.1",
Port: "80",
Labels: nil,
Status: api.HealthPassing,
},
{
ID: "id2",
Node: "Node2",
Name: "Test2",
Address: "127.0.0.1",
Port: "81",
Labels: nil,
Status: api.HealthWarning,
},
{
ID: "id3",
Node: "Node3",
Name: "Test3",
Address: "127.0.0.1",
Port: "82",
Labels: nil,
Status: api.HealthCritical,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test1": {
Service: "Test1",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:81",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
{
// The "any" health status allows for all status types, including ones not yet directly included in Consul
desc: "test include 'any' health status",
strictChecks: []string{api.HealthAny},
items: []itemData{
{
ID: "id",
Node: "Node1",
Name: "Test1",
Address: "127.0.0.1",
Port: "80",
Labels: nil,
Status: api.HealthPassing,
},
{
ID: "id2",
Node: "Node2",
Name: "Test2",
Address: "127.0.0.1",
Port: "81",
Labels: nil,
Status: api.HealthWarning,
},
{
ID: "id3",
Node: "Node3",
Name: "Test3",
Address: "127.0.0.1",
Port: "82",
Labels: nil,
Status: api.HealthCritical,
},
{
ID: "id4",
Node: "Node4",
Name: "Test4",
Address: "127.0.0.1",
Port: "83",
Labels: nil,
Status: "some unsupported status",
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test1": {
Service: "Test1",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
"Test3": {
Service: "Test3",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
"Test4": {
Service: "Test4",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test1": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:81",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Test3": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:82",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"Test4": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:83",
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{
Stores: map[string]tls.Store{},
},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
var config Configuration
config.SetDefaults()
config.DefaultRule = "Host(`foo.bar`)"
if test.strictChecks != nil {
config.StrictChecks = test.strictChecks
}
p := Provider{
Configuration: config,
}
err := p.Init()
require.NoError(t, err)
for i := 0; i < len(test.items); i++ {
var err error
test.items[i].ExtraConf, err = p.getExtraConf(test.items[i].Labels)
require.NoError(t, err)
}
configuration := p.buildConfiguration(context.Background(), test.items, nil)
assert.Equal(t, test.expected, configuration)
})
}
}