diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index eb2777c32..b53f87136 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -228,6 +228,27 @@ You can declare pieces of middleware using labels starting with `traefik.http.mi If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. +### TCP + +You can declare TCP Routers and/or Services using labels. + +??? example "Declaring TCP Routers and Services" + + ```yaml + services: + my-container: + # ... + labels: + - traefik.tcp.routers.my-router.rule="HostSNI(`my-host.com`)" + - traefik.tcp.routers.my-router.rule.tls="true" + - traefik.tcp.services.my-service.loadbalancer.server.port="4123" + ``` + +!!! warning "TCP and HTTP" + + If you declare a TCP Router/Service, it will prevent Traefik from automatically create an HTTP Router/Service (like it does by default if no TCP Router/Service is defined). + You can declare both a TCP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). + ### Specific Options #### traefik.enable diff --git a/integration/docker_test.go b/integration/docker_test.go index e2088a88b..78187f53d 100644 --- a/integration/docker_test.go +++ b/integration/docker_test.go @@ -144,6 +144,43 @@ func (s *DockerSuite) TestDefaultDockerContainers(c *check.C) { c.Assert(version["Version"], checker.Equals, "swarm/1.0.0") } +func (s *DockerSuite) TestDockerContainersWithTCPLabels(c *check.C) { + tempObjects := struct { + DockerHost string + DefaultRule string + }{ + DockerHost: s.getDockerHost(), + DefaultRule: "Host(`{{ normalize .Name }}.docker.localhost`)", + } + + file := s.adaptFile(c, "fixtures/docker/simple.toml", tempObjects) + defer os.Remove(file) + + // Start a container with some labels + labels := map[string]string{ + "traefik.tcp.Routers.Super.Rule": "HostSNI(`my.super.host`)", + "traefik.tcp.Routers.Super.tls": "true", + "traefik.tcp.Services.Super.Loadbalancer.server.port": "8080", + } + + s.startContainerWithLabels(c, "containous/whoamitcp", labels, "-name", "my.super.host") + + // Start traefik + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`my.super.host`)")) + c.Assert(err, checker.IsNil) + + who, err := guessWho("127.0.0.1:8000", "my.super.host", true) + c.Assert(err, checker.IsNil) + + c.Assert(who, checker.Contains, "my.super.host") +} + func (s *DockerSuite) TestDockerContainersWithLabels(c *check.C) { tempObjects := struct { DockerHost string diff --git a/pkg/config/dyn_config.go b/pkg/config/dyn_config.go index 34848bb54..6572f65fa 100644 --- a/pkg/config/dyn_config.go +++ b/pkg/config/dyn_config.go @@ -53,6 +53,23 @@ type TCPLoadBalancerService struct { Method string `json:"method,omitempty" toml:",omitempty"` } +// Mergeable tells if the given service is mergeable. +func (l *TCPLoadBalancerService) Mergeable(loadBalancer *TCPLoadBalancerService) bool { + savedServers := l.Servers + defer func() { + l.Servers = savedServers + }() + l.Servers = nil + + savedServersLB := loadBalancer.Servers + defer func() { + loadBalancer.Servers = savedServersLB + }() + loadBalancer.Servers = nil + + return reflect.DeepEqual(l, loadBalancer) +} + // Mergeable tells if the given service is mergeable. func (l *LoadBalancerService) Mergeable(loadBalancer *LoadBalancerService) bool { savedServers := l.Servers @@ -70,6 +87,11 @@ func (l *LoadBalancerService) Mergeable(loadBalancer *LoadBalancerService) bool return reflect.DeepEqual(l, loadBalancer) } +// SetDefaults Default values for a LoadBalancerService. +func (l *TCPLoadBalancerService) SetDefaults() { + l.Method = "wrr" +} + // SetDefaults Default values for a LoadBalancerService. func (l *LoadBalancerService) SetDefaults() { l.PassHostHeader = true @@ -97,9 +119,15 @@ type Server struct { // TCPServer holds a TCP Server configuration type TCPServer struct { Address string `json:"address" label:"-"` + Port string `toml:"-" json:"-"` Weight int `json:"weight"` } +// SetDefaults Default values for a Server. +func (s *TCPServer) SetDefaults() { + s.Weight = 1 +} + // SetDefaults Default values for a Server. func (s *Server) SetDefaults() { s.Weight = 1 diff --git a/pkg/provider/configuration.go b/pkg/provider/configuration.go index b233d881d..b80781aca 100644 --- a/pkg/provider/configuration.go +++ b/pkg/provider/configuration.go @@ -36,6 +36,12 @@ func Merge(ctx context.Context, configurations map[string]*config.Configuration) routersToDelete := map[string]struct{}{} routers := map[string][]string{} + servicesTCPToDelete := map[string]struct{}{} + servicesTCP := map[string][]string{} + + routersTCPToDelete := map[string]struct{}{} + routersTCP := map[string][]string{} + middlewaresToDelete := map[string]struct{}{} middlewares := map[string][]string{} @@ -61,6 +67,20 @@ func Merge(ctx context.Context, configurations map[string]*config.Configuration) } } + for serviceName, service := range conf.TCP.Services { + servicesTCP[serviceName] = append(servicesTCP[serviceName], root) + if !AddServiceTCP(configuration.TCP, serviceName, service) { + servicesTCPToDelete[serviceName] = struct{}{} + } + } + + for routerName, router := range conf.TCP.Routers { + routersTCP[routerName] = append(routersTCP[routerName], root) + if !AddRouterTCP(configuration.TCP, routerName, router) { + routersTCPToDelete[routerName] = struct{}{} + } + } + for middlewareName, middleware := range conf.HTTP.Middlewares { middlewares[middlewareName] = append(middlewares[middlewareName], root) if !AddMiddleware(configuration.HTTP, middlewareName, middleware) { @@ -81,6 +101,18 @@ func Merge(ctx context.Context, configurations map[string]*config.Configuration) delete(configuration.HTTP.Routers, routerName) } + for serviceName := range servicesTCPToDelete { + logger.WithField(log.ServiceName, serviceName). + Errorf("Service TCP defined multiple times with different configurations in %v", servicesTCP[serviceName]) + delete(configuration.TCP.Services, serviceName) + } + + for routerName := range routersTCPToDelete { + logger.WithField(log.RouterName, routerName). + Errorf("Router TCP defined multiple times with different configurations in %v", routersTCP[routerName]) + delete(configuration.TCP.Routers, routerName) + } + for middlewareName := range middlewaresToDelete { logger.WithField(log.MiddlewareName, middlewareName). Errorf("Middleware defined multiple times with different configurations in %v", middlewares[middlewareName]) @@ -90,6 +122,31 @@ func Merge(ctx context.Context, configurations map[string]*config.Configuration) return configuration } +// AddServiceTCP Adds a service to a configurations. +func AddServiceTCP(configuration *config.TCPConfiguration, serviceName string, service *config.TCPService) bool { + if _, ok := configuration.Services[serviceName]; !ok { + configuration.Services[serviceName] = service + return true + } + + if !configuration.Services[serviceName].LoadBalancer.Mergeable(service.LoadBalancer) { + return false + } + + configuration.Services[serviceName].LoadBalancer.Servers = append(configuration.Services[serviceName].LoadBalancer.Servers, service.LoadBalancer.Servers...) + return true +} + +// AddRouterTCP Adds a router to a configurations. +func AddRouterTCP(configuration *config.TCPConfiguration, routerName string, router *config.TCPRouter) bool { + if _, ok := configuration.Routers[routerName]; !ok { + configuration.Routers[routerName] = router + return true + } + + return reflect.DeepEqual(configuration.Routers[routerName], router) +} + // AddService Adds a service to a configurations. func AddService(configuration *config.HTTPConfiguration, serviceName string, service *config.Service) bool { if _, ok := configuration.Services[serviceName]; !ok { @@ -137,10 +194,33 @@ func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*tem return template.New("defaultRule").Funcs(defaultFuncMap).Parse(defaultRule) } +// BuildTCPRouterConfiguration Builds a router configuration. +func BuildTCPRouterConfiguration(ctx context.Context, configuration *config.TCPConfiguration) { + for routerName, router := range configuration.Routers { + loggerRouter := log.FromContext(ctx).WithField(log.RouterName, routerName) + if len(router.Rule) == 0 { + delete(configuration.Routers, routerName) + loggerRouter.Errorf("Empty rule") + continue + } + + if len(router.Service) == 0 { + if len(configuration.Services) > 1 { + delete(configuration.Routers, routerName) + loggerRouter. + Error("Could not define the service name for the router: too many services") + continue + } + + for serviceName := range configuration.Services { + router.Service = serviceName + } + } + } +} + // BuildRouterConfiguration Builds a router configuration. func BuildRouterConfiguration(ctx context.Context, configuration *config.HTTPConfiguration, defaultRouterName string, defaultRuleTpl *template.Template, model interface{}) { - logger := log.FromContext(ctx) - if len(configuration.Routers) == 0 { if len(configuration.Services) > 1 { log.FromContext(ctx).Info("Could not create a router for the container: too many services") @@ -151,7 +231,7 @@ func BuildRouterConfiguration(ctx context.Context, configuration *config.HTTPCon } for routerName, router := range configuration.Routers { - loggerRouter := logger.WithField(log.RouterName, routerName) + loggerRouter := log.FromContext(ctx).WithField(log.RouterName, routerName) if len(router.Rule) == 0 { writer := &bytes.Buffer{} if err := defaultRuleTpl.Execute(writer, model); err != nil { diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go index 893c65a22..8bb6a83ec 100644 --- a/pkg/provider/docker/config.go +++ b/pkg/provider/docker/config.go @@ -33,6 +33,21 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [ continue } + if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 { + err := p.buildTCPServiceConfiguration(ctxContainer, container, confFromLabel.TCP) + if err != nil { + logger.Error(err) + continue + } + provider.BuildTCPRouterConfiguration(ctxContainer, confFromLabel.TCP) + if len(confFromLabel.HTTP.Routers) == 0 && + len(confFromLabel.HTTP.Middlewares) == 0 && + len(confFromLabel.HTTP.Services) == 0 { + configurations[containerName] = confFromLabel + continue + } + } + err = p.buildServiceConfiguration(ctxContainer, container, confFromLabel.HTTP) if err != nil { logger.Error(err) @@ -57,6 +72,28 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [ return provider.Merge(ctx, configurations) } +func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, container dockerData, configuration *config.TCPConfiguration) error { + serviceName := getServiceName(container) + + if len(configuration.Services) == 0 { + configuration.Services = make(map[string]*config.TCPService) + lb := &config.TCPLoadBalancerService{} + lb.SetDefaults() + configuration.Services[serviceName] = &config.TCPService{ + LoadBalancer: lb, + } + } + + for _, service := range configuration.Services { + err := p.addServerTCP(ctx, container, service.LoadBalancer) + if err != nil { + return err + } + } + + return nil +} + func (p *Provider) buildServiceConfiguration(ctx context.Context, container dockerData, configuration *config.HTTPConfiguration) error { serviceName := getServiceName(container) @@ -102,6 +139,36 @@ func (p *Provider) keepContainer(ctx context.Context, container dockerData) bool return true } +func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadBalancer *config.TCPLoadBalancerService) error { + serverPort := "" + if loadBalancer != nil && len(loadBalancer.Servers) > 0 { + serverPort = loadBalancer.Servers[0].Port + } + ip, port, err := p.getIPPort(ctx, container, serverPort) + if err != nil { + return err + } + + if len(loadBalancer.Servers) == 0 { + server := config.TCPServer{} + server.SetDefaults() + + loadBalancer.Servers = []config.TCPServer{server} + } + + if serverPort != "" { + port = serverPort + loadBalancer.Servers[0].Port = "" + } + + if port == "" { + return errors.New("port is missing") + } + + loadBalancer.Servers[0].Address = net.JoinHostPort(ip, port) + return nil +} + func (p *Provider) addServer(ctx context.Context, container dockerData, loadBalancer *config.LoadBalancerService) error { serverPort := getLBServerPort(loadBalancer) ip, port, err := p.getIPPort(ctx, container, serverPort) diff --git a/pkg/provider/docker/config_test.go b/pkg/provider/docker/config_test.go index ebab2b95d..a6644d627 100644 --- a/pkg/provider/docker/config_test.go +++ b/pkg/provider/docker/config_test.go @@ -19,7 +19,7 @@ func TestDefaultRule(t *testing.T) { desc string containers []dockerData defaultRule string - expected *config.HTTPConfiguration + expected *config.Configuration }{ { desc: "default rule with no variable", @@ -42,25 +42,31 @@ func TestDefaultRule(t *testing.T) { }, }, defaultRule: "Host(`foo.bar`)", - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`foo.bar`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`foo.bar`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -87,25 +93,31 @@ func TestDefaultRule(t *testing.T) { }, }, defaultRule: "Host(`{{ .Name }}.foo.bar`)", - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.foo.bar`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.foo.bar`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -134,25 +146,31 @@ func TestDefaultRule(t *testing.T) { }, }, defaultRule: `Host("{{ .Name }}.{{ index .Labels "traefik.domain" }}")`, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: `Host("Test.foo.bar")`, - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: `Host("Test.foo.bar")`, + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -179,20 +197,26 @@ func TestDefaultRule(t *testing.T) { }, }, defaultRule: `Host("{{ .Toto }}")`, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -219,20 +243,26 @@ func TestDefaultRule(t *testing.T) { }, }, defaultRule: ``, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -259,25 +289,31 @@ func TestDefaultRule(t *testing.T) { }, }, defaultRule: DefaultTemplateRule, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -287,7 +323,6 @@ func TestDefaultRule(t *testing.T) { for _, test := range testCases { test := test - t.Run(test.desc, func(t *testing.T) { t.Parallel() @@ -307,7 +342,7 @@ func TestDefaultRule(t *testing.T) { configuration := p.buildConfiguration(context.Background(), test.containers) - assert.Equal(t, test.expected, configuration.HTTP) + assert.Equal(t, test.expected, configuration) }) } } @@ -317,7 +352,7 @@ func Test_buildConfiguration(t *testing.T) { desc string containers []dockerData constraints types.Constraints - expected *config.HTTPConfiguration + expected *config.Configuration }{ { desc: "one container no label", @@ -339,25 +374,31 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -399,41 +440,47 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, - "Test2": { - Service: "Test2", - Rule: "Host(`Test2.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - }, - Method: "wrr", - PassHostHeader: true, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + }, + "Test2": { + Service: "Test2", + Rule: "Host(`Test2.traefik.wtf`)", }, }, - "Test2": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.2:80", - Weight: 1, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, + }, + }, + "Test2": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, + }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -477,29 +524,35 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -527,25 +580,31 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Service1": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Service1", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "drr", + PassHostHeader: true, }, - Method: "drr", - PassHostHeader: true, }, }, }, @@ -575,25 +634,31 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Service1": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Router1": { + Service: "Service1", + Rule: "Host(`foo.com`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -621,26 +686,32 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, - }, - Routers: map[string]*config.Router{ - "Router1": { - Service: "Test", - Rule: "Host(`foo.com`)", + Routers: map[string]*config.Router{ + "Router1": { + Service: "Test", + Rule: "Host(`foo.com`)", + }, }, }, }, @@ -668,25 +739,31 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Service1": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Router1": { + Service: "Service1", + Rule: "Host(`foo.com`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -716,32 +793,38 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Service1": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, - }, - "Service2": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + "Service2": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -789,15 +872,21 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Service1", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{}, }, }, { @@ -861,15 +950,21 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Service1", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{}, }, }, { @@ -914,29 +1009,35 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Service1": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Service1", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, }, + Method: "drr", + PassHostHeader: true, }, - Method: "drr", - PassHostHeader: true, }, }, }, @@ -964,32 +1065,38 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - }, - Method: "wrr", - PassHostHeader: true, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", }, }, - }, - Middlewares: map[string]*config.Middleware{ - "Middleware1": { - MaxConn: &config.MaxConn{ - Amount: 42, - ExtractorFunc: "request.host", + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + }, + Method: "wrr", + PassHostHeader: true, + }, + }, + }, + Middlewares: map[string]*config.Middleware{ + "Middleware1": { + MaxConn: &config.MaxConn{ + Amount: 42, + ExtractorFunc: "request.host", + }, }, }, }, @@ -1037,36 +1144,42 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{ - "Middleware1": { - MaxConn: &config.MaxConn{ - Amount: 42, - ExtractorFunc: "request.host", + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", }, }, - }, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, - }, + Middlewares: map[string]*config.Middleware{ + "Middleware1": { + MaxConn: &config.MaxConn{ + Amount: 42, + ExtractorFunc: "request.host", + }, + }, + }, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, + }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1114,29 +1227,35 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1203,33 +1322,39 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, - }, - { - URL: "http://127.0.0.3:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, + { + URL: "http://127.0.0.3:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1277,24 +1402,30 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1361,28 +1492,34 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, - }, - { - URL: "http://127.0.0.3:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, + { + URL: "http://127.0.0.3:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1430,29 +1567,35 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Router1": { - Service: "Test", - Rule: "Host(`foo.com`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, - }, - { - URL: "http://127.0.0.2:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Router1": { + Service: "Test", + Rule: "Host(`foo.com`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1498,32 +1641,38 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, - }, - "Test2": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.2:80", - Weight: 1, + "Test2": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1551,25 +1700,31 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1598,25 +1753,31 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Service1": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "h2c://127.0.0.1:8080", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Service1", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "h2c://127.0.0.1:8080", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1645,32 +1806,38 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Service1": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, - }, - "Service2": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:8080", - Weight: 1, + "Service2": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:8080", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1694,10 +1861,16 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, }, }, { @@ -1720,10 +1893,16 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, }, }, { @@ -1748,10 +1927,16 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, }, }, { @@ -1775,10 +1960,16 @@ func Test_buildConfiguration(t *testing.T) { Health: "not_healthy", }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, }, }, { @@ -1810,10 +2001,16 @@ func Test_buildConfiguration(t *testing.T) { Regex: "bar", }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{}, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, }, }, { @@ -1845,25 +2042,31 @@ func Test_buildConfiguration(t *testing.T) { Regex: "foo", }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{}, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, }, + Method: "wrr", + PassHostHeader: true, }, - Method: "wrr", - PassHostHeader: true, }, }, }, @@ -1892,37 +2095,345 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - expected: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - Middlewares: []string{"Middleware1"}, - }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, }, - Middlewares: map[string]*config.Middleware{ - "Middleware1": { - BasicAuth: &config.BasicAuth{ - Users: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Test", + Rule: "Host(`Test.traefik.wtf`)", + Middlewares: []string{"Middleware1"}, }, }, - }, - Services: map[string]*config.Service{ - "Test": { - LoadBalancer: &config.LoadBalancerService{ - Servers: []config.Server{ - { - URL: "http://127.0.0.1:80", - Weight: 1, + Middlewares: map[string]*config.Middleware{ + "Middleware1": { + BasicAuth: &config.BasicAuth{ + Users: []string{ + "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", }, }, - Method: "wrr", - PassHostHeader: true, }, }, + Services: map[string]*config.Service{ + "Test": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + }, + Method: "wrr", + PassHostHeader: true, + }, + }, + }, + }, + }, + }, + { + desc: "tcp with label", + containers: []dockerData{ + { + ServiceName: "Test", + Name: "Test", + Labels: map[string]string{ + "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", + "traefik.tcp.routers.foo.tls": "true", + }, + NetworkSettings: networkSettings{ + Ports: nat.PortMap{ + nat.Port("80/tcp"): []nat.PortBinding{}, + }, + Networks: map[string]*networkData{ + "bridge": { + Name: "bridge", + Addr: "127.0.0.1", + }, + }, + }, + }, + }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + Service: "Test", + Rule: "HostSNI(`foo.bar`)", + TLS: &config.RouterTCPTLSConfig{}, + }, + }, + Services: map[string]*config.TCPService{ + "Test": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:80", + Weight: 1, + }, + }, + Method: "wrr", + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "tcp with label without rule", + containers: []dockerData{ + { + ServiceName: "Test", + Name: "Test", + Labels: map[string]string{ + "traefik.tcp.routers.foo.tls": "true", + }, + NetworkSettings: networkSettings{ + Ports: nat.PortMap{ + nat.Port("80/tcp"): []nat.PortBinding{}, + }, + Networks: map[string]*networkData{ + "bridge": { + Name: "bridge", + Addr: "127.0.0.1", + }, + }, + }, + }, + }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{ + "Test": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:80", + Weight: 1, + }, + }, + Method: "wrr", + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "tcp with label and port", + containers: []dockerData{ + { + ServiceName: "Test", + 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": "8080", + }, + NetworkSettings: networkSettings{ + Ports: nat.PortMap{ + nat.Port("80/tcp"): []nat.PortBinding{}, + }, + Networks: map[string]*networkData{ + "bridge": { + Name: "bridge", + Addr: "127.0.0.1", + }, + }, + }, + }, + }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + Service: "foo", + Rule: "HostSNI(`foo.bar`)", + TLS: &config.RouterTCPTLSConfig{}, + }, + }, + Services: map[string]*config.TCPService{ + "foo": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:8080", + Weight: 1, + }, + }, + Method: "wrr", + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "tcp with label and port and http service", + containers: []dockerData{ + { + ServiceName: "Test", + 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": "8080", + "traefik.http.services.Service1.loadbalancer.method": "drr", + }, + NetworkSettings: networkSettings{ + Ports: nat.PortMap{ + nat.Port("80/tcp"): []nat.PortBinding{}, + }, + Networks: map[string]*networkData{ + "bridge": { + Name: "bridge", + Addr: "127.0.0.1", + }, + }, + }, + }, + { + ID: "2", + ServiceName: "Test", + 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": "8080", + "traefik.http.services.Service1.loadbalancer.method": "drr", + }, + NetworkSettings: networkSettings{ + Ports: nat.PortMap{ + nat.Port("80/tcp"): []nat.PortBinding{}, + }, + Networks: map[string]*networkData{ + "bridge": { + Name: "bridge", + Addr: "127.0.0.2", + }, + }, + }, + }, + }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + Service: "foo", + Rule: "HostSNI(`foo.bar`)", + TLS: &config.RouterTCPTLSConfig{}, + }, + }, + Services: map[string]*config.TCPService{ + "foo": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:8080", + Weight: 1, + }, + { + Address: "127.0.0.2:8080", + Weight: 1, + }, + }, + Method: "wrr", + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "Test": { + Service: "Service1", + Rule: "Host(`Test.traefik.wtf`)", + }, + }, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{ + "Service1": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:80", + Weight: 1, + }, + { + URL: "http://127.0.0.2:80", + Weight: 1, + }, + }, + Method: "drr", + PassHostHeader: true, + }, + }, + }, + }, + }, + }, + { + desc: "tcp with label for tcp service", + containers: []dockerData{ + { + ServiceName: "Test", + Name: "Test", + Labels: map[string]string{ + "traefik.tcp.services.foo.loadbalancer.server.port": "8080", + }, + NetworkSettings: networkSettings{ + Ports: nat.PortMap{ + nat.Port("80/tcp"): []nat.PortBinding{}, + }, + Networks: map[string]*networkData{ + "bridge": { + Name: "bridge", + Addr: "127.0.0.1", + }, + }, + }, + }, + }, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{ + "foo": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:8080", + Weight: 1, + }, + }, + Method: "wrr", + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, }, }, }, @@ -1951,7 +2462,7 @@ func Test_buildConfiguration(t *testing.T) { configuration := p.buildConfiguration(context.Background(), test.containers) - assert.Equal(t, test.expected, configuration.HTTP) + assert.Equal(t, test.expected, configuration) }) } }