Auth support in frontends for k8s and file

This commit is contained in:
Mikael Rapp 2018-07-02 11:52:04 +02:00 committed by Traefiker Bot
parent e8e36bd9d5
commit bb14ec70bd
14 changed files with 867 additions and 181 deletions

View file

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"os"
"reflect"
"testing"
"time"
@ -1032,7 +1031,7 @@ rateset:
),
frontend("basic/auth",
passHostHeader(),
basicAuth("myUser:myEncodedPW"),
basicAuthDeprecated("myUser:myEncodedPW"),
routes(
route("/auth", "PathPrefix:/auth"),
route("basic", "Host:basic")),
@ -1680,7 +1679,7 @@ func TestMissingResources(t *testing.T) {
assert.Equal(t, expected, actual)
}
func TestBasicAuthInTemplate(t *testing.T) {
func TestLoadIngressesBasicAuth(t *testing.T) {
ingresses := []*extensionsv1beta1.Ingress{
buildIngress(
iNamespace("testing"),
@ -1734,9 +1733,372 @@ func TestBasicAuthInTemplate(t *testing.T) {
actual = provider.loadConfig(*actual)
require.NotNil(t, actual)
got := actual.Frontends["basic/auth"].BasicAuth
if !reflect.DeepEqual(got, []string{"myUser:myEncodedPW"}) {
t.Fatalf("unexpected credentials: %+v", got)
got := actual.Frontends["basic/auth"].Auth.Basic.Users
assert.Equal(t, types.Users{"myUser:myEncodedPW"}, got)
}
func TestLoadIngressesForwardAuth(t *testing.T) {
ingresses := []*extensionsv1beta1.Ingress{
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesAuthType, "forward"),
iAnnotation(annotationKubernetesAuthForwardURL, "https://auth.host"),
iAnnotation(annotationKubernetesAuthForwardTrustHeaders, "true"),
iAnnotation(annotationKubernetesAuthForwardResponseHeaders, "X-Auth,X-Test,X-Secret"),
iRules(
iRule(iHost("foo"),
iPaths(
onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
services := []*corev1.Service{
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
}
endpoints := []*corev1.Endpoints{
buildEndpoint(
eNamespace("testing"),
eName("service1"),
eUID("1"),
subset(
eAddresses(eAddress("10.10.0.1")),
ePorts(ePort(8080, ""))),
),
}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
watchChan: watchChan,
}
provider := Provider{}
actual, err := provider.loadIngresses(client)
require.NoError(t, err, "error loading ingresses")
expected := buildConfiguration(
backends(
backend("foo/bar",
lbMethod("wrr"),
servers(
server("http://10.10.0.1:8080", weight(1))),
),
),
frontends(
frontend("foo/bar",
passHostHeader(),
auth(forwardAuth("https://auth.host",
fwdTrustForwardHeader(),
fwdAuthResponseHeaders("X-Auth", "X-Test", "X-Secret"))),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
),
)
assert.Equal(t, expected, actual)
}
func TestLoadIngressesForwardAuthMissingURL(t *testing.T) {
ingresses := []*extensionsv1beta1.Ingress{
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesAuthType, "forward"),
iRules(
iRule(iHost("foo"),
iPaths(
onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
services := []*corev1.Service{
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
}
endpoints := []*corev1.Endpoints{
buildEndpoint(
eNamespace("testing"),
eName("service1"),
eUID("1"),
subset(
eAddresses(eAddress("10.10.0.1")),
ePorts(ePort(8080, ""))),
),
}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
watchChan: watchChan,
}
provider := Provider{}
actual, err := provider.loadIngresses(client)
require.NoError(t, err, "error loading ingresses")
expected := buildConfiguration(
backends(
backend("foo/bar",
lbMethod("wrr"),
servers(),
),
),
frontends(),
)
assert.Equal(t, expected, actual)
}
func TestLoadIngressesForwardAuthWithTLSSecret(t *testing.T) {
ingresses := []*extensionsv1beta1.Ingress{
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesAuthType, "forward"),
iAnnotation(annotationKubernetesAuthForwardURL, "https://auth.host"),
iAnnotation(annotationKubernetesAuthForwardTLSSecret, "secret"),
iAnnotation(annotationKubernetesAuthForwardTLSInsecure, "true"),
iRules(
iRule(iHost("foo"),
iPaths(
onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
secrets := []*corev1.Secret{{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
UID: "1",
Namespace: "testing",
},
Data: map[string][]byte{
"tls.crt": []byte("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
"tls.key": []byte("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
}}
services := []*corev1.Service{
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
}
endpoints := []*corev1.Endpoints{
buildEndpoint(
eNamespace("testing"),
eName("service1"),
eUID("1"),
subset(
eAddresses(eAddress("10.10.0.1")),
ePorts(ePort(8080, ""))),
),
}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
secrets: secrets,
watchChan: watchChan,
}
provider := Provider{}
actual, err := provider.loadIngresses(client)
require.NoError(t, err, "error loading ingresses")
expected := buildConfiguration(
backends(
backend("foo/bar",
lbMethod("wrr"),
servers(
server("http://10.10.0.1:8080", weight(1))),
),
),
frontends(
frontend("foo/bar",
passHostHeader(),
auth(
forwardAuth("https://auth.host",
fwdAuthTLS(
"-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
"-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----",
true))),
routes(
route("/bar", "PathPrefix:/bar"),
route("foo", "Host:foo")),
),
),
)
assert.Equal(t, expected, actual)
}
func TestLoadIngressesForwardAuthWithTLSSecretFailures(t *testing.T) {
tests := []struct {
desc string
secretName string
certName string
certData string
keyName string
keyData string
}{
{
desc: "empty certificate and key",
secretName: "secret",
certName: "",
certData: "",
keyName: "",
keyData: "",
},
{
desc: "wrong secret name, empty certificate and key",
secretName: "wrongSecret",
certName: "",
certData: "",
keyName: "",
keyData: "",
},
{
desc: "empty certificate data",
secretName: "secret",
certName: "tls.crt",
certData: "",
keyName: "tls.key",
keyData: "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----",
},
{
desc: "empty key data",
secretName: "secret",
certName: "tls.crt",
certData: "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
keyName: "tls.key",
keyData: "",
},
{
desc: "wrong cert name",
secretName: "secret",
certName: "cert.crt",
certData: "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE----",
keyName: "tls.key",
keyData: "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----",
},
{
desc: "wrong key name",
secretName: "secret",
certName: "tls.crt",
certData: "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
keyName: "cert.key",
keyData: "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----",
},
}
ingresses := []*extensionsv1beta1.Ingress{
buildIngress(
iNamespace("testing"),
iAnnotation(annotationKubernetesAuthType, "forward"),
iAnnotation(annotationKubernetesAuthForwardURL, "https://auth.host"),
iAnnotation(annotationKubernetesAuthForwardTLSSecret, "secret"),
iRules(
iRule(iHost("foo"),
iPaths(
onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))),
),
),
}
services := []*corev1.Service{
buildService(
sName("service1"),
sNamespace("testing"),
sUID("1"),
sSpec(
clusterIP("10.0.0.1"),
sPorts(sPort(80, ""))),
),
}
endpoints := []*corev1.Endpoints{
buildEndpoint(
eNamespace("testing"),
eName("service1"),
eUID("1"),
subset(
eAddresses(eAddress("10.10.0.1")),
ePorts(ePort(8080, ""))),
),
}
for _, test := range tests {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
secrets := []*corev1.Secret{{
ObjectMeta: metav1.ObjectMeta{
Name: test.secretName,
UID: "1",
Namespace: "testing",
},
Data: map[string][]byte{
test.certName: []byte(test.certData),
test.keyName: []byte(test.keyData),
},
}}
watchChan := make(chan interface{})
client := clientMock{
ingresses: ingresses,
services: services,
endpoints: endpoints,
secrets: secrets,
watchChan: watchChan,
}
provider := Provider{}
actual, err := provider.loadIngresses(client)
require.NoError(t, err, "error loading ingresses")
expected := buildConfiguration(
backends(
backend("foo/bar",
lbMethod("wrr"),
servers(),
),
),
frontends(),
)
assert.Equal(t, expected, actual)
})
}
}