Auth support in frontends for k8s and file
This commit is contained in:
parent
e8e36bd9d5
commit
bb14ec70bd
14 changed files with 867 additions and 181 deletions
|
@ -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)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue