751 lines
18 KiB
Go
751 lines
18 KiB
Go
package rancher
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/containous/traefik/pkg/config"
|
|
"github.com/containous/traefik/pkg/types"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func Test_buildConfiguration(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
containers []rancherData
|
|
constraints []*types.Constraint
|
|
expected *config.Configuration
|
|
}{
|
|
{
|
|
desc: "one service no label",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
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: "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",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "two services no label",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test1",
|
|
Labels: map[string]string{},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
{
|
|
Name: "Test2",
|
|
Labels: map[string]string{},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.2"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
expected: &config.Configuration{
|
|
TCP: &config.TCPConfiguration{
|
|
Routers: map[string]*config.TCPRouter{},
|
|
Services: map[string]*config.TCPService{},
|
|
},
|
|
HTTP: &config.HTTPConfiguration{
|
|
Routers: map[string]*config.Router{
|
|
"Test1": {
|
|
Service: "Test1",
|
|
Rule: "Host(`Test1.traefik.wtf`)",
|
|
},
|
|
"Test2": {
|
|
Service: "Test2",
|
|
Rule: "Host(`Test2.traefik.wtf`)",
|
|
},
|
|
},
|
|
Middlewares: map[string]*config.Middleware{},
|
|
Services: map[string]*config.Service{
|
|
"Test1": {
|
|
LoadBalancer: &config.LoadBalancerService{
|
|
Servers: []config.Server{
|
|
{
|
|
URL: "http://127.0.0.1:80",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
"Test2": {
|
|
LoadBalancer: &config.LoadBalancerService{
|
|
Servers: []config.Server{
|
|
{
|
|
URL: "http://127.0.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "two services no label multiple containers",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test1",
|
|
Labels: map[string]string{},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1", "127.0.0.2"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
{
|
|
Name: "Test2",
|
|
Labels: map[string]string{},
|
|
Port: "80/tcp",
|
|
Containers: []string{"128.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
expected: &config.Configuration{
|
|
TCP: &config.TCPConfiguration{
|
|
Routers: map[string]*config.TCPRouter{},
|
|
Services: map[string]*config.TCPService{},
|
|
},
|
|
HTTP: &config.HTTPConfiguration{
|
|
Routers: map[string]*config.Router{
|
|
"Test1": {
|
|
Service: "Test1",
|
|
Rule: "Host(`Test1.traefik.wtf`)",
|
|
},
|
|
"Test2": {
|
|
Service: "Test2",
|
|
Rule: "Host(`Test2.traefik.wtf`)",
|
|
},
|
|
},
|
|
Middlewares: map[string]*config.Middleware{},
|
|
Services: map[string]*config.Service{
|
|
"Test1": {
|
|
LoadBalancer: &config.LoadBalancerService{
|
|
Servers: []config.Server{
|
|
{
|
|
URL: "http://127.0.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://127.0.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
"Test2": {
|
|
LoadBalancer: &config.LoadBalancerService{
|
|
Servers: []config.Server{
|
|
{
|
|
URL: "http://128.0.0.1:80",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "one service some labels",
|
|
containers: []rancherData{
|
|
{
|
|
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",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
expected: &config.Configuration{
|
|
TCP: &config.TCPConfiguration{
|
|
Routers: map[string]*config.TCPRouter{},
|
|
Services: map[string]*config.TCPService{},
|
|
},
|
|
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",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "one service which is unhealthy",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "broken",
|
|
State: "",
|
|
},
|
|
},
|
|
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{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "one service which is upgrading",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "upgradefailed",
|
|
},
|
|
},
|
|
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{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "one service with rule label and has a host exposed port",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
|
|
},
|
|
Port: "12345:80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
expected: &config.Configuration{
|
|
TCP: &config.TCPConfiguration{
|
|
Routers: map[string]*config.TCPRouter{},
|
|
Services: map[string]*config.TCPService{},
|
|
},
|
|
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",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "one service with non matching constraints",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
|
|
},
|
|
Port: "12345:80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
constraints: []*types.Constraint{
|
|
{
|
|
Key: "tag",
|
|
MustMatch: true,
|
|
Value: "bar",
|
|
},
|
|
},
|
|
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{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "one service with matching constraints",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.tags": "foo",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
constraints: []*types.Constraint{
|
|
{
|
|
Key: "tag",
|
|
MustMatch: true,
|
|
Value: "foo",
|
|
},
|
|
},
|
|
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: "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",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Middlewares used in router",
|
|
containers: []rancherData{
|
|
{
|
|
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",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
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: "Test",
|
|
Rule: "Host(`Test.traefik.wtf`)",
|
|
Middlewares: []string{"Middleware1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*config.Middleware{
|
|
"Middleware1": {
|
|
BasicAuth: &config.BasicAuth{
|
|
Users: []string{
|
|
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
|
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*config.Service{
|
|
"Test": {
|
|
LoadBalancer: &config.LoadBalancerService{
|
|
Servers: []config.Server{
|
|
{
|
|
URL: "http://127.0.0.1:80",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Port in labels",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.http.services.Test.loadbalancer.server.port": "80",
|
|
},
|
|
Port: "",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
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: "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",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "tcp with label",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
|
|
"traefik.tcp.routers.foo.tls": "true",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
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",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
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: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.tcp.routers.foo.tls": "true",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
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",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
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: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
|
|
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
expected: &config.Configuration{
|
|
TCP: &config.TCPConfiguration{
|
|
Routers: map[string]*config.TCPRouter{
|
|
"foo": {
|
|
Service: "foo",
|
|
Rule: "HostSNI(`foo.bar`)",
|
|
},
|
|
},
|
|
Services: map[string]*config.TCPService{
|
|
"foo": {
|
|
LoadBalancer: &config.TCPLoadBalancerService{
|
|
Servers: []config.TCPServer{
|
|
{
|
|
Address: "127.0.0.1:8080",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
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: []rancherData{
|
|
{
|
|
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.passhostheader": "true",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1", "127.0.0.2"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
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",
|
|
},
|
|
{
|
|
Address: "127.0.0.2:8080",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
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",
|
|
},
|
|
{
|
|
URL: "http://127.0.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "tcp with label for tcp service",
|
|
containers: []rancherData{
|
|
{
|
|
Name: "Test",
|
|
Labels: map[string]string{
|
|
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
|
|
},
|
|
Port: "80/tcp",
|
|
Containers: []string{"127.0.0.1"},
|
|
Health: "",
|
|
State: "",
|
|
},
|
|
},
|
|
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",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
HTTP: &config.HTTPConfiguration{
|
|
Routers: map[string]*config.Router{},
|
|
Middlewares: map[string]*config.Middleware{},
|
|
Services: map[string]*config.Service{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
test := test
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
p := Provider{
|
|
ExposedByDefault: true,
|
|
DefaultRule: "Host(`{{ normalize .Name }}.traefik.wtf`)",
|
|
EnableServiceHealthFilter: true,
|
|
}
|
|
|
|
p.Constraints = test.constraints
|
|
|
|
err := p.Init()
|
|
require.NoError(t, err)
|
|
|
|
for i := 0; i < len(test.containers); i++ {
|
|
var err error
|
|
test.containers[i].ExtraConf, err = p.getConfiguration(test.containers[i])
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
configuration := p.buildConfiguration(context.Background(), test.containers)
|
|
|
|
assert.Equal(t, test.expected, configuration)
|
|
})
|
|
}
|
|
}
|