traefik/provider/kubernetes/kubernetes_test.go

1191 lines
26 KiB
Go
Raw Normal View History

package kubernetes
import (
"errors"
"fmt"
"reflect"
"testing"
"github.com/containous/traefik/provider/label"
"github.com/stretchr/testify/assert"
2017-12-05 19:24:03 +00:00
"github.com/stretchr/testify/require"
2017-04-07 10:49:53 +00:00
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/pkg/util/intstr"
)
func TestLoadIngresses(t *testing.T) {
2017-12-05 19:24:03 +00:00
ingresses := []*v1beta1.Ingress{
buildIngress(
iNamespace("testing"),
iRules(
iRule(iHost("foo"),
iPaths(
onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))),
onePath(iPath("/namedthing"), iBackend("service4", intstr.FromString("https")))),
),
iRule(iHost("bar"),
iPaths(
onePath(iBackend("service3", intstr.FromString("https"))),
onePath(iBackend("service2", intstr.FromInt(802)))),
),
),
),
}
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
buildService(
sName("service2"),
sNamespace("testing"),
sUID("2"),
sSpec(
clusterIP("10.0.0.2"),
sPorts(sPort(802, ""))),
),
buildService(
sName("service3"),
sNamespace("testing"),
sUID("3"),
sSpec(
clusterIP("10.0.0.3"),
sPorts(
sPort(80, "http"),
sPort(443, "https")),
),
),
buildService(
sName("service4"),
sNamespace("testing"),
sUID("4"),
sSpec(
clusterIP("10.0.0.4"),
sType("ExternalName"),
sExternalName("example.com"),
sPorts(sPort(443, "https"))),
),
}
2017-12-05 19:24:03 +00:00
endpoints := []*v1.Endpoints{
2017-12-05 19:24:03 +00:00
buildEndpoint(
eNamespace("testing"),
eName("service1"),
eUID("1"),
subset(
eAddresses(eAddress("10.10.0.1")),
ePorts(ePort(8080, ""))),
subset(
eAddresses(eAddress("10.21.0.1")),
ePorts(ePort(8080, ""))),
),
buildEndpoint(
eNamespace("testing"),
eName("service3"),
eUID("3"),
subset(
eAddresses(eAddress("10.15.0.1")),
ePorts(
ePort(8080, "http"),
ePort(8443, "https")),
),
subset(
eAddresses(eAddress("10.15.0.2")),
ePorts(
ePort(9080, "http"),
ePort(9443, "https")),
),
),
}
2017-12-05 19:24:03 +00:00
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(
backend("foo/bar",
lbMethod("wrr"),
servers(
server("http://10.10.0.1:8080", weight(1)),
server("http://10.21.0.1:8080", weight(1))),
),
backend("foo/namedthing",
lbMethod("wrr"),
servers(server("https://example.com", weight(1))),
),
backend("bar",
lbMethod("wrr"),
servers(
server("https://10.15.0.1:8443", weight(1)),
server("https://10.15.0.2:9443", weight(1))),
),
),
frontends(
frontend("foo/bar",
passHostHeader(),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
frontend("foo/namedthing",
passHostHeader(),
routes(
route("/namedthing", "PathPrefix:/namedthing"),
route("foo", "Host:foo")),
),
frontend("bar",
passHostHeader(),
routes(route("bar", "Host:bar")),
),
),
)
2017-08-18 14:14:03 +00:00
assert.Equal(t, expected, actual)
}
func TestRuleType(t *testing.T) {
tests := []struct {
desc string
ingressRuleType string
frontendRuleType string
}{
{
desc: "rule type annotation missing",
ingressRuleType: "",
frontendRuleType: ruleTypePathPrefix,
},
{
desc: "Path rule type annotation set",
ingressRuleType: "Path",
frontendRuleType: "Path",
},
{
desc: "PathStrip rule type annotation set",
ingressRuleType: "PathStrip",
frontendRuleType: "PathStrip",
},
{
desc: "PathStripPrefix rule type annotation set",
ingressRuleType: "PathStripPrefix",
frontendRuleType: "PathStripPrefix",
},
}
for _, test := range tests {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
2017-12-05 19:24:03 +00:00
ingress := buildIngress(iRules(iRule(
iHost("host"),
iPaths(
onePath(iPath("/path"), iBackend("service", intstr.FromInt(80))),
),
)))
if test.ingressRuleType != "" {
ingress.ObjectMeta.Annotations = map[string]string{
label.TraefikFrontendRuleType: test.ingressRuleType,
}
}
2017-12-05 19:24:03 +00:00
service := buildService(
sName("service"),
sUID("1"),
sSpec(sPorts(sPort(801, "http"))),
)
watchChan := make(chan interface{})
client := clientMock{
ingresses: []*v1beta1.Ingress{ingress},
services: []*v1.Service{service},
watchChan: watchChan,
}
provider := Provider{DisablePassHostHeaders: true}
2017-12-05 19:24:03 +00:00
actualConfig, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildFrontends(frontend("host/path",
routes(
route("/path", fmt.Sprintf("%s:/path", test.frontendRuleType)),
route("host", "Host:host")),
))
2017-12-05 19:24:03 +00:00
assert.Equal(t, expected, actualConfig.Frontends)
})
}
}
func TestGetPassHostHeader(t *testing.T) {
2017-12-05 19:24:03 +00:00
ingresses := []*v1beta1.Ingress{
buildIngress(
iNamespace("awesome"),
iRules(iRule(
iHost("foo"),
iPaths(onePath(
iPath("/bar"),
iBackend("service1", intstr.FromInt(801)))),
)),
),
}
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sNamespace("awesome"), sName("service1"), sUID("1"),
sSpec(sPorts(sPort(801, "http"))),
),
}
2017-12-05 19:24:03 +00:00
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
watchChan: watchChan,
}
provider := Provider{DisablePassHostHeaders: true}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(backend("foo/bar", lbMethod("wrr"), servers())),
frontends(
frontend("foo/bar",
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
),
)
2017-08-18 14:14:03 +00:00
assert.Equal(t, expected, actual)
}
func TestGetPassTLSCert(t *testing.T) {
2017-12-05 19:24:03 +00:00
ingresses := []*v1beta1.Ingress{
buildIngress(iNamespace("awesome"),
iRules(iRule(
iHost("foo"),
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("awesome"),
sUID("1"),
sSpec(sPorts(sPort(801, "http"))),
),
}
2017-12-05 19:24:03 +00:00
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
watchChan: watchChan,
}
provider := Provider{EnablePassTLSCert: true}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(backend("foo/bar", lbMethod("wrr"), servers())),
frontends(frontend("foo/bar",
passHostHeader(),
passTLSCert(),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
)),
)
assert.Equal(t, expected, actual)
}
func TestOnlyReferencesServicesFromOwnNamespace(t *testing.T) {
ingresses := []*v1beta1.Ingress{
2017-12-05 19:24:03 +00:00
buildIngress(iNamespace("awesome"),
iRules(iRule(
iHost("foo"),
iPaths(onePath(iBackend("service", intstr.FromInt(80))))),
),
),
}
2017-12-05 19:24:03 +00:00
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sNamespace("awesome"),
sName("service"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, "http"))),
),
buildService(
sNamespace("not-awesome"),
sName("service"),
sUID("2"),
sSpec(
clusterIP("10.0.0.2"),
sPorts(sPort(80, "http"))),
),
}
2017-12-05 19:24:03 +00:00
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(backend("foo", lbMethod("wrr"), servers())),
frontends(frontend("foo",
passHostHeader(),
routes(route("foo", "Host:foo")),
)),
)
2017-08-18 14:14:03 +00:00
assert.Equal(t, expected, actual)
}
func TestHostlessIngress(t *testing.T) {
2017-12-05 19:24:03 +00:00
ingresses := []*v1beta1.Ingress{
buildIngress(iNamespace("awesome"),
iRules(iRule(
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(801))))),
),
),
}
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("awesome"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(801, "http"))),
),
}
2017-12-05 19:24:03 +00:00
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
watchChan: watchChan,
}
provider := Provider{DisablePassHostHeaders: true}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(backend("/bar", lbMethod("wrr"), servers())),
frontends(frontend("/bar", routes(route("/bar", "PathPrefix:/bar")))),
)
2017-08-18 14:14:03 +00:00
assert.Equal(t, expected, actual)
}
func TestServiceAnnotations(t *testing.T) {
2017-12-05 19:24:03 +00:00
ingresses := []*v1beta1.Ingress{
buildIngress(iNamespace("testing"),
iRules(
iRule(
iHost("foo"),
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
iRule(
iHost("bar"),
iPaths(onePath(iBackend("service2", intstr.FromInt(802))))),
),
),
}
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sAnnotation(label.TraefikBackendCircuitBreaker, "NetworkErrorRatio() > 0.5"),
sAnnotation(label.TraefikBackendLoadBalancerMethod, "drr"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
buildService(
sName("service2"),
sNamespace("testing"),
sUID("2"),
sAnnotation(label.TraefikBackendCircuitBreaker, ""),
sAnnotation(label.TraefikBackendLoadBalancerSticky, "true"),
sSpec(
clusterIP("10.0.0.2"),
sPorts(sPort(802, ""))),
),
}
2017-12-05 19:24:03 +00:00
endpoints := []*v1.Endpoints{
2017-12-05 19:24:03 +00:00
buildEndpoint(
eNamespace("testing"),
eName("service1"),
eUID("1"),
subset(
eAddresses(eAddress("10.10.0.1")),
ePorts(ePort(8080, ""))),
subset(
eAddresses(eAddress("10.21.0.1")),
ePorts(ePort(8080, ""))),
),
buildEndpoint(
eNamespace("testing"),
eName("service2"),
eUID("2"),
subset(
eAddresses(eAddress("10.15.0.1")),
ePorts(ePort(8080, "http"))),
subset(
eAddresses(eAddress("10.15.0.2")),
ePorts(ePort(8080, "http"))),
),
}
2017-12-05 19:24:03 +00:00
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(
backend("foo/bar",
servers(
server("http://10.10.0.1:8080", weight(1)),
server("http://10.21.0.1:8080", weight(1))),
lbMethod("drr"),
circuitBreaker("NetworkErrorRatio() > 0.5"),
),
backend("bar",
servers(
server("http://10.15.0.1:8080", weight(1)),
server("http://10.15.0.2:8080", weight(1))),
lbMethod("wrr"), lbSticky(),
),
),
frontends(
frontend("foo/bar",
passHostHeader(),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
frontend("bar",
passHostHeader(),
routes(route("bar", "Host:bar"))),
),
)
2017-10-16 15:38:03 +00:00
assert.EqualValues(t, expected, actual)
}
func TestIngressAnnotations(t *testing.T) {
ingresses := []*v1beta1.Ingress{
2017-12-05 19:24:03 +00:00
buildIngress(
iNamespace("testing"),
iAnnotation(label.TraefikFrontendPassHostHeader, "false"),
iRules(
iRule(
iHost("foo"),
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(label.TraefikFrontendPassHostHeader, "true"),
iAnnotation(annotationKubernetesIngressClass, "traefik"),
iRules(
iRule(
iHost("other"),
iPaths(onePath(iPath("/stuff"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(label.TraefikFrontendPassTLSCert, "true"),
iAnnotation(annotationKubernetesIngressClass, "traefik"),
iRules(
iRule(
iHost("other"),
iPaths(onePath(iPath("/sslstuff"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(label.TraefikFrontendEntryPoints, "http,https"),
iAnnotation(annotationKubernetesIngressClass, "traefik"),
iRules(
iRule(
iHost("other"),
iPaths(onePath(iPath("/"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesAuthType, "basic"),
iAnnotation(annotationKubernetesAuthSecret, "mySecret"),
iRules(
iRule(
iHost("basic"),
iPaths(onePath(iPath("/auth"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesIngressClass, "somethingOtherThanTraefik"),
iRules(
iRule(
iHost("herp"),
iPaths(onePath(iPath("/derp"), iBackend("service2", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesIngressClass, "traefik"),
iAnnotation(annotationKubernetesWhitelistSourceRange, "1.1.1.1/24, 1234:abcd::42/32"),
iRules(
iRule(
iHost("test"),
iPaths(onePath(iPath("/whitelist-source-range"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesRewriteTarget, "/"),
iRules(
iRule(
iHost("rewrite"),
iPaths(onePath(iPath("/api"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesAuthRealm, "customized"),
iRules(
iRule(
iHost("auth-realm-customized"),
iPaths(onePath(iPath("/auth-realm-customized"), iBackend("service1", intstr.FromInt(80))))),
),
),
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesIngressClass, "traefik"),
2017-12-15 21:16:48 +00:00
iAnnotation(label.TraefikFrontendRedirectEntryPoint, "https"),
2017-12-05 19:24:03 +00:00
iRules(
iRule(
iHost("redirect"),
iPaths(onePath(iPath("/https"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
2017-12-05 19:24:03 +00:00
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sType("ExternalName"),
sExternalName("example.com"),
sPorts(sPort(80, "http"))),
),
buildService(
sName("service2"),
sNamespace("testing"),
sUID("2"),
sSpec(
clusterIP("10.0.0.2"),
sPorts(sPort(802, ""))),
),
}
2017-12-05 19:24:03 +00:00
secrets := []*v1.Secret{{
ObjectMeta: v1.ObjectMeta{
Name: "mySecret",
UID: "1",
Namespace: "testing",
2017-04-23 14:17:20 +00:00
},
2017-12-05 19:24:03 +00:00
Data: map[string][]byte{"auth": []byte("myUser:myEncodedPW")},
}}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
2017-04-23 14:17:20 +00:00
secrets: secrets,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(
backend("foo/bar",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
backend("other/stuff",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
backend("other/",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
backend("other/sslstuff",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
backend("basic/auth",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
backend("redirect/https",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
backend("test/whitelist-source-range",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
backend("rewrite/api",
servers(
server("http://example.com", weight(1)),
server("http://example.com", weight(1))),
lbMethod("wrr"),
),
),
frontends(
frontend("foo/bar",
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
frontend("other/stuff",
passHostHeader(),
routes(
route("/stuff", "PathPrefix:/stuff"),
route("other", "Host:other")),
),
frontend("other/",
passHostHeader(),
entryPoints("http", "https"),
routes(
route("/", "PathPrefix:/"),
route("other", "Host:other")),
),
frontend("other/sslstuff",
passHostHeader(),
passTLSCert(),
routes(
route("/sslstuff", "PathPrefix:/sslstuff"),
route("other", "Host:other")),
),
frontend("other/sslstuff",
passHostHeader(),
passTLSCert(),
routes(
route("/sslstuff", "PathPrefix:/sslstuff"),
route("other", "Host:other")),
),
frontend("basic/auth",
passHostHeader(),
basicAuth("myUser:myEncodedPW"),
routes(
route("/auth", "PathPrefix:/auth"),
route("basic", "Host:basic")),
),
frontend("redirect/https",
passHostHeader(),
2017-12-15 21:16:48 +00:00
redirectEntryPoint("https"),
2017-12-05 19:24:03 +00:00
routes(
route("/https", "PathPrefix:/https"),
route("redirect", "Host:redirect")),
),
frontend("test/whitelist-source-range",
passHostHeader(),
whitelistSourceRange("1.1.1.1/24", "1234:abcd::42/32"),
routes(
route("/whitelist-source-range", "PathPrefix:/whitelist-source-range"),
route("test", "Host:test")),
),
frontend("rewrite/api",
passHostHeader(),
routes(
route("/api", "PathPrefix:/api;ReplacePath:/"),
route("rewrite", "Host:rewrite")),
),
),
)
assert.Equal(t, expected, actual)
}
func TestPriorityHeaderValue(t *testing.T) {
ingresses := []*v1beta1.Ingress{
2017-12-05 19:24:03 +00:00
buildIngress(
iNamespace("testing"),
iAnnotation(label.TraefikFrontendPriority, "1337"),
iRules(
iRule(
iHost("foo"),
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
2017-12-05 19:24:03 +00:00
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sType("ExternalName"),
sExternalName("example.com"),
sPorts(sPort(80, "http"))),
),
}
2017-12-05 19:24:03 +00:00
var endpoints []*v1.Endpoints
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(
backend("foo/bar",
servers(server("http://example.com", weight(1))),
lbMethod("wrr"),
),
),
frontends(
frontend("foo/bar",
passHostHeader(),
priority(1337),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
),
)
assert.Equal(t, expected, actual)
}
func TestInvalidPassTLSCertValue(t *testing.T) {
ingresses := []*v1beta1.Ingress{
2017-12-05 19:24:03 +00:00
buildIngress(
iNamespace("testing"),
iAnnotation(label.TraefikFrontendPassTLSCert, "herpderp"),
iRules(
iRule(
iHost("foo"),
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
2017-12-05 19:24:03 +00:00
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sType("ExternalName"),
sExternalName("example.com"),
sPorts(sPort(80, "http"))),
),
}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(
backend("foo/bar",
servers(server("http://example.com", weight(1))),
lbMethod("wrr"),
),
),
frontends(
frontend("foo/bar",
passHostHeader(),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
),
)
assert.Equal(t, expected, actual)
}
func TestInvalidPassHostHeaderValue(t *testing.T) {
ingresses := []*v1beta1.Ingress{
2017-12-05 19:24:03 +00:00
buildIngress(
iNamespace("testing"),
iAnnotation(label.TraefikFrontendPassHostHeader, "herpderp"),
iRules(
iRule(
iHost("foo"),
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
2017-12-05 19:24:03 +00:00
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sType("ExternalName"),
sExternalName("example.com"),
sPorts(sPort(80, "http"))),
),
}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(
backend("foo/bar",
servers(server("http://example.com", weight(1))),
lbMethod("wrr"),
),
),
frontends(
frontend("foo/bar",
passHostHeader(),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
),
)
2017-08-18 14:14:03 +00:00
assert.Equal(t, expected, actual)
}
func TestKubeAPIErrors(t *testing.T) {
2017-12-05 19:24:03 +00:00
ingresses := []*v1beta1.Ingress{
buildIngress(
iNamespace("testing"),
iRules(
iRule(
iHost("foo"),
iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
2017-12-05 19:24:03 +00:00
services := []*v1.Service{
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
}
watchChan := make(chan interface{})
apiErr := errors.New("failed kube api call")
testCases := []struct {
desc string
apiServiceErr error
apiEndpointsErr error
}{
{
desc: "failed service call",
apiServiceErr: apiErr,
},
{
desc: "failed endpoints call",
apiEndpointsErr: apiErr,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
t.Parallel()
client := clientMock{
ingresses: ingresses,
services: services,
watchChan: watchChan,
apiServiceError: tc.apiServiceErr,
apiEndpointsError: tc.apiEndpointsErr,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
if _, err := provider.loadIngresses(client); err != apiErr {
t.Errorf("Got error %v, wanted error %v", err, apiErr)
}
})
}
}
func TestMissingResources(t *testing.T) {
2017-12-05 19:24:03 +00:00
ingresses := []*v1beta1.Ingress{
buildIngress(
iNamespace("testing"),
iRules(
iRule(
iHost("fully_working"),
iPaths(onePath(iBackend("fully_working_service", intstr.FromInt(80))))),
iRule(
iHost("missing_service"),
iPaths(onePath(iBackend("missing_service_service", intstr.FromInt(80))))),
iRule(
iHost("missing_endpoints"),
iPaths(onePath(iBackend("missing_endpoints_service", intstr.FromInt(80))))),
iRule(
iHost("missing_endpoint_subsets"),
iPaths(onePath(iBackend("missing_endpoint_subsets_service", intstr.FromInt(80))))),
),
),
}
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("fully_working_service"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
buildService(
sName("missing_endpoints_service"),
sNamespace("testing"),
sUID("3"),
sSpec(
clusterIP("10.0.0.3"),
sPorts(sPort(80, ""))),
),
buildService(
sName("missing_endpoint_subsets_service"),
sNamespace("testing"),
sUID("4"),
sSpec(
clusterIP("10.0.0.4"),
sPorts(sPort(80, ""))),
),
}
2017-12-05 19:24:03 +00:00
endpoints := []*v1.Endpoints{
2017-12-05 19:24:03 +00:00
buildEndpoint(
eName("fully_working_service"),
eUID("1"),
eNamespace("testing"),
subset(
eAddresses(eAddress("10.10.0.1")),
ePorts(ePort(8080, ""))),
),
buildEndpoint(
eName("missing_endpoint_subsets_service"),
eUID("4"),
eNamespace("testing"),
subset(),
),
}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-12-05 19:24:03 +00:00
expected := buildConfiguration(
backends(
backend("fully_working",
servers(server("http://10.10.0.1:8080", weight(1))),
lbMethod("wrr"),
),
backend("missing_service",
servers(),
lbMethod("wrr"),
),
backend("missing_endpoints",
servers(),
lbMethod("wrr"),
),
backend("missing_endpoint_subsets",
servers(),
lbMethod("wrr"),
),
),
frontends(
frontend("fully_working",
passHostHeader(),
routes(route("fully_working", "Host:fully_working")),
),
frontend("missing_endpoints",
passHostHeader(),
routes(route("missing_endpoints", "Host:missing_endpoints")),
),
frontend("missing_endpoint_subsets",
passHostHeader(),
routes(route("missing_endpoint_subsets", "Host:missing_endpoint_subsets")),
),
),
)
2017-08-18 14:14:03 +00:00
assert.Equal(t, expected, actual)
}
2017-04-23 14:17:20 +00:00
func TestBasicAuthInTemplate(t *testing.T) {
ingresses := []*v1beta1.Ingress{
2017-12-05 19:24:03 +00:00
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesAuthType, "basic"),
iAnnotation(annotationKubernetesAuthSecret, "mySecret"),
iRules(
iRule(
iHost("basic"),
iPaths(onePath(iPath("/auth"), iBackend("service1", intstr.FromInt(80))))),
),
),
2017-04-23 14:17:20 +00:00
}
2017-12-05 19:24:03 +00:00
2017-04-23 14:17:20 +00:00
services := []*v1.Service{
2017-12-05 19:24:03 +00:00
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sType("ExternalName"),
sExternalName("example.com"),
sPorts(sPort(80, "http"))),
),
2017-04-23 14:17:20 +00:00
}
2017-12-05 19:24:03 +00:00
secrets := []*v1.Secret{{
ObjectMeta: v1.ObjectMeta{
Name: "mySecret",
UID: "1",
Namespace: "testing",
2017-04-23 14:17:20 +00:00
},
2017-12-05 19:24:03 +00:00
Data: map[string][]byte{
"auth": []byte("myUser:myEncodedPW"),
},
}}
2017-04-23 14:17:20 +00:00
2017-12-05 19:24:03 +00:00
var endpoints []*v1.Endpoints
2017-04-23 14:17:20 +00:00
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
secrets: secrets,
endpoints: endpoints,
watchChan: watchChan,
}
provider := Provider{}
2017-12-05 19:24:03 +00:00
2017-04-23 14:17:20 +00:00
actual, err := provider.loadIngresses(client)
2017-12-05 19:24:03 +00:00
require.NoError(t, err, "error loading ingresses")
2017-04-23 14:17:20 +00:00
actual = provider.loadConfig(*actual)
2017-12-15 10:48:03 +00:00
require.NotNil(t, actual)
2017-04-23 14:17:20 +00:00
got := actual.Frontends["basic/auth"].BasicAuth
if !reflect.DeepEqual(got, []string{"myUser:myEncodedPW"}) {
t.Fatalf("unexpected credentials: %+v", got)
}
}