From 09062b40e514d4392ec82de92c903fde81565255 Mon Sep 17 00:00:00 2001 From: Rohit Ramkumar Date: Thu, 15 Mar 2018 07:56:50 -0700 Subject: [PATCH] Add ingress e2e test for multiple TLS (SNI) support --- test/e2e/framework/ingress_utils.go | 19 ++++++++-- test/e2e/network/ingress.go | 36 +++++++++++++++++++ .../ingress/multiple-certs/ing.yaml | 34 ++++++++++++++++++ .../ingress/multiple-certs/rc.yaml | 16 +++++++++ .../ingress/multiple-certs/svc.yaml | 15 ++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 test/e2e/testing-manifests/ingress/multiple-certs/ing.yaml create mode 100644 test/e2e/testing-manifests/ingress/multiple-certs/rc.yaml create mode 100644 test/e2e/testing-manifests/ingress/multiple-certs/svc.yaml diff --git a/test/e2e/framework/ingress_utils.go b/test/e2e/framework/ingress_utils.go index 2339632f43c..9e3e145fb86 100644 --- a/test/e2e/framework/ingress_utils.go +++ b/test/e2e/framework/ingress_utils.go @@ -1213,18 +1213,33 @@ func (j *IngressTestJig) Update(update func(ing *extensions.Ingress)) { // AddHTTPS updates the ingress to use this secret for these hosts. func (j *IngressTestJig) AddHTTPS(secretName string, hosts ...string) { - j.Ingress.Spec.TLS = []extensions.IngressTLS{{Hosts: hosts, SecretName: secretName}} // TODO: Just create the secret in GetRootCAs once we're watching secrets in // the ingress controller. _, cert, _, err := createTLSSecret(j.Client, j.Ingress.Namespace, secretName, hosts...) ExpectNoError(err) j.Logger.Infof("Updating ingress %v to use secret %v for TLS termination", j.Ingress.Name, secretName) j.Update(func(ing *extensions.Ingress) { - ing.Spec.TLS = []extensions.IngressTLS{{Hosts: hosts, SecretName: secretName}} + ing.Spec.TLS = append(ing.Spec.TLS, extensions.IngressTLS{Hosts: hosts, SecretName: secretName}) }) j.RootCAs[secretName] = cert } +// RemoveHTTPS updates the ingress to not use this secret for TLS. +// Note: Does not delete the secret. +func (j *IngressTestJig) RemoveHTTPS(secretName string) { + newTLS := []extensions.IngressTLS{} + for _, ingressTLS := range j.Ingress.Spec.TLS { + if secretName != ingressTLS.SecretName { + newTLS = append(newTLS, ingressTLS) + } + } + j.Logger.Infof("Updating ingress %v to not use secret %v for TLS termination", j.Ingress.Name, secretName) + j.Update(func(ing *extensions.Ingress) { + ing.Spec.TLS = newTLS + }) + delete(j.RootCAs, secretName) +} + // PrepareTLSSecret creates a TLS secret and caches the cert. func (j *IngressTestJig) PrepareTLSSecret(namespace, secretName string, hosts ...string) error { _, cert, _, err := createTLSSecret(j.Client, namespace, secretName, hosts...) diff --git a/test/e2e/network/ingress.go b/test/e2e/network/ingress.go index 25a25b3ef0d..9e99dc61452 100644 --- a/test/e2e/network/ingress.go +++ b/test/e2e/network/ingress.go @@ -311,6 +311,42 @@ var _ = SIGDescribe("Loadbalancing: L7", func() { executeBacksideBacksideHTTPSTest(f, jig, "") }) + It("should support multiple TLS certs [Unreleased]", func() { + By("Creating an ingress with no certs.") + jig.CreateIngress(filepath.Join(framework.IngressManifestPath, "multiple-certs"), ns, map[string]string{ + framework.IngressStaticIPKey: ns, + }, map[string]string{}) + + By("Adding multiple certs to the ingress.") + hosts := []string{"test1.ingress.com", "test2.ingress.com", "test3.ingress.com", "test4.ingress.com"} + secrets := []string{"tls-secret-1", "tls-secret-2", "tls-secret-3", "tls-secret-4"} + certs := [][]byte{} + for i, host := range hosts { + jig.AddHTTPS(secrets[i], host) + certs = append(certs, jig.GetRootCA(secrets[i])) + } + for i, host := range hosts { + err := jig.WaitForIngressWithCert(true, []string{host}, certs[i]) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Unexpected error while waiting for ingress: %v", err)) + } + + By("Remove all but one of the certs on the ingress.") + jig.RemoveHTTPS(secrets[1]) + jig.RemoveHTTPS(secrets[2]) + jig.RemoveHTTPS(secrets[3]) + + By("Test that the remaining cert is properly served.") + err := jig.WaitForIngressWithCert(true, []string{hosts[0]}, certs[0]) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Unexpected error while waiting for ingress: %v", err)) + + By("Add back one of the certs that was removed and check that all certs are served.") + jig.AddHTTPS(secrets[1], hosts[1]) + for i, host := range hosts[:2] { + err := jig.WaitForIngressWithCert(true, []string{host}, certs[i]) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Unexpected error while waiting for ingress: %v", err)) + } + }) + It("multicluster ingress should get instance group annotation", func() { name := "echomap" jig.CreateIngress(filepath.Join(framework.IngressManifestPath, "http"), ns, map[string]string{ diff --git a/test/e2e/testing-manifests/ingress/multiple-certs/ing.yaml b/test/e2e/testing-manifests/ingress/multiple-certs/ing.yaml new file mode 100644 index 00000000000..8cda83c9e5d --- /dev/null +++ b/test/e2e/testing-manifests/ingress/multiple-certs/ing.yaml @@ -0,0 +1,34 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: multiple-certs +spec: + rules: + - host: test1.ingress.com + http: + paths: + - path: /test + backend: + serviceName: echoheaders-https + servicePort: 80 + - host: test2.ingress.com + http: + paths: + - path: /test + backend: + serviceName: echoheaders-https + servicePort: 80 + - host: test3.ingress.com + http: + paths: + - path: /test + backend: + serviceName: echoheaders-https + servicePort: 80 + - host: test4.ingress.com + http: + paths: + - path: /test + backend: + serviceName: echoheaders-https + servicePort: 80 diff --git a/test/e2e/testing-manifests/ingress/multiple-certs/rc.yaml b/test/e2e/testing-manifests/ingress/multiple-certs/rc.yaml new file mode 100644 index 00000000000..79e2bfb0259 --- /dev/null +++ b/test/e2e/testing-manifests/ingress/multiple-certs/rc.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: echoheaders-https +spec: + replicas: 2 + template: + metadata: + labels: + app: echoheaders-https + spec: + containers: + - name: echoheaders-https + image: gcr.io/google_containers/echoserver:1.10 + ports: + - containerPort: 8080 diff --git a/test/e2e/testing-manifests/ingress/multiple-certs/svc.yaml b/test/e2e/testing-manifests/ingress/multiple-certs/svc.yaml new file mode 100644 index 00000000000..b022aa17fce --- /dev/null +++ b/test/e2e/testing-manifests/ingress/multiple-certs/svc.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: echoheaders-https + labels: + app: echoheaders-https +spec: + type: NodePort + ports: + - port: 80 + targetPort: 8080 + protocol: TCP + name: http + selector: + app: echoheaders-https