Repository: knative-sandbox/net-kourier
Pull request #626 (2021-09-03 02:24:50)

Split RouteConfig for HTTP and HTTPS listeners
Currently RouteConfig (`external_services`) is used by both HTTP
Listener and HTTPS Listener when TLS is enabled.
However, to add redirect support, we cannot share the RouteConfig as
HTTPListener needs Route with `RedirectAction`.

So, this patch introduces another RouteConfig
(`external_tls_services`) for the HTTPS Listener.

Part of https://github.com/knative-sandbox/net-kourier/pull/619

knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative-sandbox/net-kourier/pull/626#" title="Author self-approved">nak3</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative-sandbox%2Fnet-kourier).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/knative-sandbox/net-kourier/blob/main/OWNERS)~~ [nak3]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
knative-metrics-robot: The following is the coverage report on the affected files.
Say `/test pull-knative-sandbox-net-kourier-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/generator/caches.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1433616951820685312/artifacts/line-cov.html#file0) | 65.1% | 68.9% | 3.8
[pkg/generator/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1433616951820685312/artifacts/line-cov.html#file1) | 88.5% | 88.2% | -0.3

codecov[bot]: # [Codecov](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox) Report
> Merging [#626](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox) (6a699c4) into [main](https://codecov.io/gh/knative-sandbox/net-kourier/commit/c722ae9333fc0b9b1a0af2c699be7fe094f3818c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox) (c722ae9) will **increase** coverage by `0.40%`.
> The diff coverage is `91.30%`.

[![Impacted file tree graph](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626/graphs/tree.svg?width=650&height=150&src=pr&token=KmlRo23zX4&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox)](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox)

```diff
@@            Coverage Diff             @@
##             main     #626      +/-   ##
==========================================
+ Coverage   71.31%   71.72%   +0.40%     
==========================================
  Files          18       18              
  Lines         617      633      +16     
==========================================
+ Hits          440      454      +14     
- Misses        151      153       +2     
  Partials       26       26              
```


| [Impacted Files](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox) | Coverage Δ | |
|---|---|---|
| [pkg/generator/caches.go](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox#diff-cGtnL2dlbmVyYXRvci9jYWNoZXMuZ28=) | `63.39% <90.00%> (+3.77%)` | :arrow_up: |
| [pkg/generator/ingress\_translator.go](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox#diff-cGtnL2dlbmVyYXRvci9pbmdyZXNzX3RyYW5zbGF0b3IuZ28=) | `82.51% <92.30%> (+0.29%)` | :arrow_up: |
| [pkg/generator/sni.go](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox#diff-cGtnL2dlbmVyYXRvci9zbmkuZ28=) | `86.66% <0.00%> (-13.34%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox). Last update [c722ae9...6a699c4](https://codecov.io/gh/knative-sandbox/net-kourier/pull/626?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=knative-sandbox).

knative-metrics-robot: The following is the coverage report on the affected files.
Say `/test pull-knative-sandbox-net-kourier-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/generator/caches.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435111887137148928/artifacts/line-cov.html#file0) | 65.1% | 68.9% | 3.8
[pkg/generator/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435111887137148928/artifacts/line-cov.html#file1) | 88.5% | 87.7% | -0.8

knative-metrics-robot: The following is the coverage report on the affected files.
Say `/test pull-knative-sandbox-net-kourier-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/generator/caches.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435114413911707648/artifacts/line-cov.html#file0) | 65.1% | 68.9% | 3.8
[pkg/generator/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435114413911707648/artifacts/line-cov.html#file1) | 88.5% | 87.7% | -0.8

knative-metrics-robot: The following is the coverage report on the affected files.
Say `/test pull-knative-sandbox-net-kourier-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/generator/caches.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435115762569187328/artifacts/line-cov.html#file0) | 65.1% | 68.9% | 3.8
[pkg/generator/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435115762569187328/artifacts/line-cov.html#file1) | 88.5% | 87.7% | -0.8

knative-metrics-robot: The following is the coverage report on the affected files.
Say `/test pull-knative-sandbox-net-kourier-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/generator/caches.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435125565102231552/artifacts/line-cov.html#file0) | 65.1% | 69.2% | 4.2
[pkg/generator/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/626/pull-knative-sandbox-net-kourier-go-coverage/1435125565102231552/artifacts/line-cov.html#file1) | 88.5% | 87.7% | -0.8

knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative-sandbox/net-kourier/pull/626#pullrequestreview-747583501" title="Approved">markusthoemmes</a>*, *<a href="https://github.com/knative-sandbox/net-kourier/pull/626#" title="Author self-approved">nak3</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative-sandbox%2Fnet-kourier).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/knative-sandbox/net-kourier/blob/main/OWNERS)~~ [markusthoemmes,nak3]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
nak3: /hold cancel

All tests passed :tada: 

Patch:
diff --git a/pkg/generator/caches.go b/pkg/generator/caches.go
index 38a903b5..40a9e2b8 100644
--- a/pkg/generator/caches.go
+++ b/pkg/generator/caches.go
@@ -39,12 +39,13 @@ import (
 )
 
 const (
-	envCertsSecretNamespace = "CERTS_SECRET_NAMESPACE"
-	envCertsSecretName      = "CERTS_SECRET_NAME"
-	certFieldInSecret       = "tls.crt"
-	keyFieldInSecret        = "tls.key"
-	externalRouteConfigName = "external_services"
-	internalRouteConfigName = "internal_services"
+	envCertsSecretNamespace    = "CERTS_SECRET_NAMESPACE"
+	envCertsSecretName         = "CERTS_SECRET_NAME"
+	certFieldInSecret          = "tls.crt"
+	keyFieldInSecret           = "tls.key"
+	externalRouteConfigName    = "external_services"
+	externalTLSRouteConfigName = "external_tls_services"
+	internalRouteConfigName    = "internal_services"
 )
 
 // ErrDomainConflict is an error produces when two ingresses have conflicting domains.
@@ -130,11 +131,13 @@ func (caches *Caches) ToEnvoySnapshot(ctx context.Context) (cache.Snapshot, erro
 
 	localVHosts := make([]*route.VirtualHost, 0, len(caches.translatedIngresses)+1)
 	externalVHosts := make([]*route.VirtualHost, 0, len(caches.translatedIngresses))
+	externalTLSVHosts := make([]*route.VirtualHost, 0, len(caches.translatedIngresses))
 	snis := sniMatches{}
 
 	for _, translatedIngress := range caches.translatedIngresses {
 		localVHosts = append(localVHosts, translatedIngress.internalVirtualHosts...)
 		externalVHosts = append(externalVHosts, translatedIngress.externalVirtualHosts...)
+		externalTLSVHosts = append(externalTLSVHosts, translatedIngress.externalTLSVirtualHosts...)
 
 		for _, match := range translatedIngress.sniMatches {
 			snis.consume(match)
@@ -146,6 +149,7 @@ func (caches *Caches) ToEnvoySnapshot(ctx context.Context) (cache.Snapshot, erro
 	listeners, routes, err := generateListenersAndRouteConfigs(
 		ctx,
 		externalVHosts,
+		externalTLSVHosts,
 		localVHosts,
 		snis.list(),
 		caches.kubeClient,
@@ -200,6 +204,7 @@ func (caches *Caches) deleteTranslatedIngress(ingressName, ingressNamespace stri
 func generateListenersAndRouteConfigs(
 	ctx context.Context,
 	externalVirtualHosts []*route.VirtualHost,
+	externalTLSVirtualHosts []*route.VirtualHost,
 	clusterLocalVirtualHosts []*route.VirtualHost,
 	sniMatches []*envoy.SNIMatch,
 	kubeclient kubeclient.Interface) ([]cachetypes.Resource, []cachetypes.Resource, error) {
@@ -211,6 +216,7 @@ func generateListenersAndRouteConfigs(
 
 	// First, we save the RouteConfigs with the proper name and all the virtualhosts etc. into the cache.
 	externalRouteConfig := envoy.NewRouteConfig(externalRouteConfigName, externalVirtualHosts)
+	externalTLSRouteConfig := envoy.NewRouteConfig(externalTLSRouteConfigName, externalTLSVirtualHosts)
 	internalRouteConfig := envoy.NewRouteConfig(internalRouteConfigName, clusterLocalVirtualHosts)
 
 	// Without this we can generate routes that point to non-existing clusters
@@ -218,10 +224,12 @@ func generateListenersAndRouteConfigs(
 	// in the Knative serving test suite fails sometimes.
 	// Ref: https://github.com/knative/serving/blob/f6da03e5dfed78593c4f239c3c7d67c5d7c55267/test/conformance/ingress/update_test.go#L37
 	externalRouteConfig.ValidateClusters = wrapperspb.Bool(true)
+	externalTLSRouteConfig.ValidateClusters = wrapperspb.Bool(true)
 	internalRouteConfig.ValidateClusters = wrapperspb.Bool(true)
 
 	// Now we setup connection managers, that reference the routeconfigs via RDS.
 	externalManager := envoy.NewHTTPConnectionManager(externalRouteConfig.Name, cfg.Kourier.EnableServiceAccessLogging)
+	externalTLSManager := envoy.NewHTTPConnectionManager(externalTLSRouteConfig.Name, cfg.Kourier.EnableServiceAccessLogging)
 	internalManager := envoy.NewHTTPConnectionManager(internalRouteConfig.Name, cfg.Kourier.EnableServiceAccessLogging)
 	externalHTTPEnvoyListener, err := envoy.NewHTTPListener(externalManager, config.HTTPPortExternal)
 	if err != nil {
@@ -233,27 +241,30 @@ func generateListenersAndRouteConfigs(
 	}
 
 	listeners := []cachetypes.Resource{externalHTTPEnvoyListener, internalEnvoyListener}
+	routes := []cachetypes.Resource{externalRouteConfig, internalRouteConfig}
 
 	// Configure TLS Listener. If there's at least one ingress that contains the
 	// TLS field, that takes precedence. If there is not, TLS will be configured
 	// using a single cert for all the services if the creds are given via ENV.
 	if len(sniMatches) > 0 {
-		externalHTTPSEnvoyListener, err := envoy.NewHTTPSListenerWithSNI(externalManager, config.HTTPSPortExternal, sniMatches)
+		externalHTTPSEnvoyListener, err := envoy.NewHTTPSListenerWithSNI(externalTLSManager, config.HTTPSPortExternal, sniMatches)
 		if err != nil {
 			return nil, nil, err
 		}
 		listeners = append(listeners, externalHTTPSEnvoyListener)
+		routes = append(routes, externalTLSRouteConfig)
 	} else if useHTTPSListenerWithOneCert() {
 		externalHTTPSEnvoyListener, err := newExternalEnvoyListenerWithOneCert(
-			ctx, externalManager, kubeclient,
+			ctx, externalTLSManager, kubeclient,
 		)
 		if err != nil {
 			return nil, nil, err
 		}
 		listeners = append(listeners, externalHTTPSEnvoyListener)
+		routes = append(routes, externalTLSRouteConfig)
 	}
 
-	return listeners, []cachetypes.Resource{externalRouteConfig, internalRouteConfig}, nil
+	return listeners, routes, nil
 }
 
 // Returns true if we need to modify the HTTPS listener with just one cert
diff --git a/pkg/generator/ingress_translator.go b/pkg/generator/ingress_translator.go
index 30db2ea0..27d92725 100644
--- a/pkg/generator/ingress_translator.go
+++ b/pkg/generator/ingress_translator.go
@@ -35,11 +35,12 @@ import (
 )
 
 type translatedIngress struct {
-	name                 types.NamespacedName
-	sniMatches           []*envoy.SNIMatch
-	clusters             []*v3.Cluster
-	externalVirtualHosts []*route.VirtualHost
-	internalVirtualHosts []*route.VirtualHost
+	name                    types.NamespacedName
+	sniMatches              []*envoy.SNIMatch
+	clusters                []*v3.Cluster
+	externalVirtualHosts    []*route.VirtualHost
+	externalTLSVirtualHosts []*route.VirtualHost
+	internalVirtualHosts    []*route.VirtualHost
 }
 
 type IngressTranslator struct {
@@ -89,12 +90,14 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 
 	internalHosts := make([]*route.VirtualHost, 0, len(ingress.Spec.Rules))
 	externalHosts := make([]*route.VirtualHost, 0, len(ingress.Spec.Rules))
+	externalTLSHosts := make([]*route.VirtualHost, 0, len(ingress.Spec.Rules))
 	clusters := make([]*v3.Cluster, 0, len(ingress.Spec.Rules))
 
 	for i, rule := range ingress.Spec.Rules {
 		ruleName := fmt.Sprintf("(%s/%s).Rules[%d]", ingress.Namespace, ingress.Name, i)
 
 		routes := make([]*route.Route, 0, len(rule.HTTP.Paths))
+		tlsRoutes := make([]*route.Route, 0, len(rule.HTTP.Paths))
 		for _, httpPath := range rule.HTTP.Paths {
 			// Default the path to "/" if none is passed.
 			path := httpPath.Path
@@ -174,6 +177,9 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 			if len(wrs) != 0 {
 				routes = append(routes, envoy.NewRoute(
 					pathName, matchHeadersFromHTTPPath(httpPath), path, wrs, 0, httpPath.AppendHeaders, httpPath.RewriteHost))
+				if len(ingress.Spec.TLS) != 0 {
+					tlsRoutes = append(tlsRoutes, routes...)
+				}
 			}
 		}
 
@@ -182,20 +188,29 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 			return nil, nil
 		}
 
-		var virtualHost *route.VirtualHost
+		var virtualHost, virtualTLSHost *route.VirtualHost
 		if extAuthzEnabled {
 			contextExtensions := kmeta.UnionMaps(map[string]string{
 				"client":     "kourier",
 				"visibility": string(rule.Visibility),
 			}, ingress.GetLabels())
 			virtualHost = envoy.NewVirtualHostWithExtAuthz(ruleName, contextExtensions, domainsForRule(rule), routes)
+			if len(tlsRoutes) != 0 {
+				virtualTLSHost = envoy.NewVirtualHostWithExtAuthz(ruleName, contextExtensions, domainsForRule(rule), tlsRoutes)
+			}
 		} else {
 			virtualHost = envoy.NewVirtualHost(ruleName, domainsForRule(rule), routes)
+			if len(tlsRoutes) != 0 {
+				virtualTLSHost = envoy.NewVirtualHost(ruleName, domainsForRule(rule), tlsRoutes)
+			}
 		}
 
 		internalHosts = append(internalHosts, virtualHost)
 		if rule.Visibility == v1alpha1.IngressVisibilityExternalIP {
 			externalHosts = append(externalHosts, virtualHost)
+			if virtualTLSHost != nil {
+				externalTLSHosts = append(externalTLSHosts, virtualTLSHost)
+			}
 		}
 	}
 
@@ -204,10 +219,11 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 			Namespace: ingress.Namespace,
 			Name:      ingress.Name,
 		},
-		sniMatches:           sniMatches,
-		clusters:             clusters,
-		externalVirtualHosts: externalHosts,
-		internalVirtualHosts: internalHosts,
+		sniMatches:              sniMatches,
+		clusters:                clusters,
+		externalVirtualHosts:    externalHosts,
+		externalTLSVirtualHosts: externalTLSHosts,
+		internalVirtualHosts:    internalHosts,
 	}, nil
 }
 


Test patch:
diff --git a/pkg/generator/caches_test.go b/pkg/generator/caches_test.go
index 021fe276..ab0d9ea0 100644
--- a/pkg/generator/caches_test.go
+++ b/pkg/generator/caches_test.go
@@ -29,6 +29,7 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/client-go/kubernetes/fake"
 	"knative.dev/net-kourier/pkg/config"
+	envoy "knative.dev/net-kourier/pkg/envoy/api"
 )
 
 func TestDeleteIngressInfo(t *testing.T) {
@@ -48,6 +49,7 @@ func TestDeleteIngressInfo(t *testing.T) {
 		"cluster_for_ingress_1",
 		"internal_host_for_ingress_1",
 		"external_host_for_ingress_1",
+		"external_tls_host_for_ingress_1",
 	)
 
 	// Add info for a different ingress
@@ -60,6 +62,7 @@ func TestDeleteIngressInfo(t *testing.T) {
 		"cluster_for_ingress_2",
 		"internal_host_for_ingress_2",
 		"external_host_for_ingress_2",
+		"external_tls_host_for_ingress_2",
 	)
 
 	// Delete the first ingress
@@ -84,6 +87,7 @@ func TestDeleteIngressInfo(t *testing.T) {
 
 	expectedNames := []string{
 		"internal_host_for_ingress_2",
+		"external_tls_host_for_ingress_2",
 		"external_host_for_ingress_2",
 		config.InternalKourierDomain,
 	}
@@ -111,6 +115,7 @@ func TestDeleteIngressInfoWhenDoesNotExist(t *testing.T) {
 		"cluster_for_ingress_1",
 		"internal_host_for_ingress_1",
 		"external_host_for_ingress_1",
+		"external_tls_host_for_ingress_1",
 	)
 
 	snapshotBeforeDelete, err := caches.ToEnvoySnapshot(ctx)
@@ -154,16 +159,23 @@ func createTestDataForIngress(
 	ingressNamespace string,
 	clusterName string,
 	internalVHostName string,
-	externalVHostName string) {
+	externalVHostName string,
+	externalTLSVHostName string) {
 
 	translatedIngress := &translatedIngress{
 		name: types.NamespacedName{
 			Namespace: ingressNamespace,
 			Name:      ingressName,
 		},
-		clusters:             []*v3.Cluster{{Name: clusterName}},
-		externalVirtualHosts: []*route.VirtualHost{{Name: externalVHostName, Domains: []string{externalVHostName}}},
-		internalVirtualHosts: []*route.VirtualHost{{Name: internalVHostName, Domains: []string{internalVHostName}}},
+		clusters:                []*v3.Cluster{{Name: clusterName}},
+		externalVirtualHosts:    []*route.VirtualHost{{Name: externalVHostName, Domains: []string{externalVHostName}}},
+		externalTLSVirtualHosts: []*route.VirtualHost{{Name: externalTLSVHostName, Domains: []string{externalTLSVHostName}}},
+		internalVirtualHosts:    []*route.VirtualHost{{Name: internalVHostName, Domains: []string{internalVHostName}}},
+		sniMatches: []*envoy.SNIMatch{{
+			Hosts:            []string{"foo.example.com"},
+			CertSource:       types.NamespacedName{Namespace: "secretns", Name: "secretname"},
+			CertificateChain: cert,
+			PrivateKey:       privateKey}},
 	}
 
 	caches.addTranslatedIngress(translatedIngress)
@@ -183,6 +195,7 @@ func TestValidateIngress(t *testing.T) {
 		"cluster_for_ingress_1",
 		"internal_host_for_ingress_1",
 		"external_host_for_ingress_1",
+		"external_tls_host_for_ingress_1",
 	)
 
 	translatedIngress := translatedIngress{
@@ -190,10 +203,16 @@ func TestValidateIngress(t *testing.T) {
 			Namespace: "ingress_2_namespace",
 			Name:      "ingress_2",
 		},
-		clusters:             []*v3.Cluster{{Name: "cluster_for_ingress_2"}},
-		externalVirtualHosts: []*route.VirtualHost{{Name: "external_host_for_ingress_2", Domains: []string{"external_host_for_ingress_2"}}},
+		clusters:                []*v3.Cluster{{Name: "cluster_for_ingress_2"}},
+		externalVirtualHosts:    []*route.VirtualHost{{Name: "external_host_for_ingress_2", Domains: []string{"external_host_for_ingress_2"}}},
+		externalTLSVirtualHosts: []*route.VirtualHost{{Name: "external_tls_host_for_ingress_2", Domains: []string{"external__tlshost_for_ingress_2"}}},
 		//This domain should clash with the cached ingress.
 		internalVirtualHosts: []*route.VirtualHost{{Name: "internal_host_for_ingress_2", Domains: []string{"internal_host_for_ingress_1"}}},
+		sniMatches: []*envoy.SNIMatch{{
+			Hosts:            []string{"foo.example.com"},
+			CertSource:       types.NamespacedName{Namespace: "secretns", Name: "secretname"},
+			CertificateChain: cert,
+			PrivateKey:       privateKey}},
 	}
 
 	err = caches.validateIngress(&translatedIngress)
diff --git a/pkg/generator/ingress_translator_test.go b/pkg/generator/ingress_translator_test.go
index 32f3c012..fbf8f707 100644
--- a/pkg/generator/ingress_translator_test.go
+++ b/pkg/generator/ingress_translator_test.go
@@ -89,8 +89,9 @@ func TestIngressTranslator(t *testing.T) {
 						v3.Cluster_STATIC,
 					),
 				},
-				externalVirtualHosts: vHosts,
-				internalVirtualHosts: vHosts,
+				externalVirtualHosts:    vHosts,
+				externalTLSVirtualHosts: []*route.VirtualHost{},
+				internalVirtualHosts:    vHosts,
 			}
 		}(),
 	}, {
@@ -154,8 +155,9 @@ func TestIngressTranslator(t *testing.T) {
 						v3.Cluster_STATIC,
 					),
 				},
-				externalVirtualHosts: vHosts,
-				internalVirtualHosts: vHosts,
+				externalVirtualHosts:    vHosts,
+				externalTLSVirtualHosts: vHosts,
+				internalVirtualHosts:    vHosts,
 			}
 		}(),
 	}, {
@@ -244,8 +246,9 @@ func TestIngressTranslator(t *testing.T) {
 						v3.Cluster_LOGICAL_DNS,
 					),
 				},
-				externalVirtualHosts: vHosts,
-				internalVirtualHosts: vHosts,
+				externalVirtualHosts:    vHosts,
+				externalTLSVirtualHosts: []*route.VirtualHost{},
+				internalVirtualHosts:    vHosts,
 			}
 		}(),
 	}, {
@@ -296,8 +299,9 @@ func TestIngressTranslator(t *testing.T) {
 						v3.Cluster_STATIC,
 					),
 				},
-				externalVirtualHosts: vHosts,
-				internalVirtualHosts: vHosts,
+				externalVirtualHosts:    vHosts,
+				externalTLSVirtualHosts: []*route.VirtualHost{},
+				internalVirtualHosts:    vHosts,
 			}
 		}(),
 	}, {
@@ -348,8 +352,9 @@ func TestIngressTranslator(t *testing.T) {
 						v3.Cluster_LOGICAL_DNS,
 					),
 				},
-				externalVirtualHosts: vHosts,
-				internalVirtualHosts: vHosts,
+				externalVirtualHosts:    vHosts,
+				externalTLSVirtualHosts: []*route.VirtualHost{},
+				internalVirtualHosts:    vHosts,
 			}
 		}(),
 	}, {