Repository: knative-sandbox/net-kourier
Pull request #371 (2020-11-19 10:02:23)

Name envoy config resources in a non-conflicting way
Newer envoy versions seem to be more sensitive to how resources are named. Especially the VirtualHosts started colliding when multiple `Rules` are at play (which is often the case in Serving).

/hold

I want to send the test into the conformance suite and test this through serving thoroughly first too.

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/371#" title="Author self-approved">markusthoemmes</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/master/OWNERS)~~ [markusthoemmes]

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/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-go-coverage/1329364400783495168/artifacts/line-cov.html#file0) | 88.3% | 88.9% | 0.6

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/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-go-coverage/1329375518541221888/artifacts/line-cov.html#file0) | 88.3% | 88.9% | 0.6

knative-prow-robot: @markusthoemmes: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-net-kourier-build-tests | 787b970157f009e606facba56b47c9dc4d0f2b0f | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-build-tests/1329375518478307328) | `/test pull-knative-sandbox-net-kourier-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_net-kourier/371). [Your PR dashboard](https://gubernator.knative.dev/pr/markusthoemmes).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
markusthoemmes: Verified to work in https://github.com/knative/serving/pull/10151
markusthoemmes: /assign @jmprusi @davidor 
knative-prow-robot: @markusthoemmes: PR needs rebase.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
knative-prow-robot: @markusthoemmes: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-net-kourier-build-tests | 787b970157f009e606facba56b47c9dc4d0f2b0f | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-build-tests/1329375518478307328) | `/test pull-knative-sandbox-net-kourier-build-tests`
pull-knative-sandbox-net-kourier-unit-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-unit-tests/1329450037712785408) | `/test pull-knative-sandbox-net-kourier-unit-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_net-kourier/371). [Your PR dashboard](https://gubernator.knative.dev/pr/markusthoemmes).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @markusthoemmes: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-net-kourier-build-tests | 787b970157f009e606facba56b47c9dc4d0f2b0f | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-build-tests/1329375518478307328) | `/test pull-knative-sandbox-net-kourier-build-tests`
pull-knative-sandbox-net-kourier-unit-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-unit-tests/1329450037712785408) | `/test pull-knative-sandbox-net-kourier-unit-tests`
pull-knative-sandbox-net-kourier-integration-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-integration-tests/1329450037742145536) | `/test pull-knative-sandbox-net-kourier-integration-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_net-kourier/371). [Your PR dashboard](https://gubernator.knative.dev/pr/markusthoemmes).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @markusthoemmes: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-net-kourier-build-tests | 787b970157f009e606facba56b47c9dc4d0f2b0f | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-build-tests/1329375518478307328) | `/test pull-knative-sandbox-net-kourier-build-tests`
pull-knative-sandbox-net-kourier-unit-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-unit-tests/1329450037712785408) | `/test pull-knative-sandbox-net-kourier-unit-tests`
pull-knative-sandbox-net-kourier-integration-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-integration-tests/1329450037742145536) | `/test pull-knative-sandbox-net-kourier-integration-tests`
pull-knative-sandbox-net-kourier-go-coverage | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-go-coverage/1329450037767311360) | `/test pull-knative-sandbox-net-kourier-go-coverage`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_net-kourier/371). [Your PR dashboard](https://gubernator.knative.dev/pr/markusthoemmes).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @markusthoemmes: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-net-kourier-unit-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-unit-tests/1329450037712785408) | `/test pull-knative-sandbox-net-kourier-unit-tests`
pull-knative-sandbox-net-kourier-integration-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-integration-tests/1329450037742145536) | `/test pull-knative-sandbox-net-kourier-integration-tests`
pull-knative-sandbox-net-kourier-go-coverage | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-go-coverage/1329450037767311360) | `/test pull-knative-sandbox-net-kourier-go-coverage`
pull-knative-sandbox-net-kourier-build-tests | 2f56d3715dc827e7b530b80357c3a72a79cce9f2 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-build-tests/1329450037683425280) | `/test pull-knative-sandbox-net-kourier-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_net-kourier/371). [Your PR dashboard](https://gubernator.knative.dev/pr/markusthoemmes).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
markusthoemmes: /unhold

Ready to go forward.
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/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-go-coverage/1329450498142507008/artifacts/line-cov.html#file0) | 88.3% | 88.9% | 0.6

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/ingress_translator.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative-sandbox_net-kourier/371/pull-knative-sandbox-net-kourier-go-coverage/1329451126637989888/artifacts/line-cov.html#file0) | 88.3% | 88.5% | 0.2


Patch:
diff --git a/.github/workflows/knative-releasability.yaml b/.github/workflows/knative-releasability.yaml
index f13cc479..ca0820a6 100644
--- a/.github/workflows/knative-releasability.yaml
+++ b/.github/workflows/knative-releasability.yaml
@@ -142,7 +142,7 @@ jobs:
           echo 'SLACK_TITLE=Releasability for ${{ github.repository }} @ ${{ env.RELEASE }} is NO-GO!' >> $GITHUB_ENV
 
       - name: Post status to Slack
-        if: steps.exists.outputs.release-branch == 'false'
+        if: ${{ secrets.SLACK_WEBHOOK != '' && steps.exists.outputs.release-branch == 'false' }}
         uses: rtCamp/action-slack-notify@v2.1.0
         env:
           SLACK_ICON: http://github.com/knative.png?size=48
diff --git a/go.mod b/go.mod
index d186e1cc..f65c5c00 100644
--- a/go.mod
+++ b/go.mod
@@ -19,6 +19,6 @@ require (
 	k8s.io/apimachinery v0.18.12
 	k8s.io/client-go v0.18.12
 	knative.dev/hack v0.0.0-20201119025252-d3cb354f49ff
-	knative.dev/networking v0.0.0-20201119023952-faeea4d06427
+	knative.dev/networking v0.0.0-20201119153452-ac0823abbb90
 	knative.dev/pkg v0.0.0-20201119021551-260026d54739
 )
diff --git a/go.sum b/go.sum
index e3117471..6898f99e 100644
--- a/go.sum
+++ b/go.sum
@@ -1112,16 +1112,12 @@ k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29/go.mod h1:F+5wygcW0wmRTnM
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE=
 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-knative.dev/hack v0.0.0-20201112185459-01a34c573bd8 h1:RNbZsAjhswBPtl4C5C5gEFX5/GfWIOZQxfYD9DhkHdY=
-knative.dev/hack v0.0.0-20201112185459-01a34c573bd8/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
 knative.dev/hack v0.0.0-20201118155651-b31d3bb6bff9 h1:OgYL1cATsWTS6kztSOuQqhmYfcn6ZdpPAQQ6TKCx00I=
 knative.dev/hack v0.0.0-20201118155651-b31d3bb6bff9/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
 knative.dev/hack v0.0.0-20201119025252-d3cb354f49ff h1:+bdPPtgog4EAuibiiW1uMdWX2DVij0+elXSh+Yfey78=
 knative.dev/hack v0.0.0-20201119025252-d3cb354f49ff/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
-knative.dev/networking v0.0.0-20201119023952-faeea4d06427 h1:JHpzPRDnADEo32O/0oHn/vMQMbK55qAVCzDmFw3g7xM=
-knative.dev/networking v0.0.0-20201119023952-faeea4d06427/go.mod h1:kUYwYHjpttuBQOy/NFELDC047Phehof+m2aU0C3k7u8=
-knative.dev/pkg v0.0.0-20201117221452-0fccc54273ed h1:4LNEFhvD2Ya4WgCD3SC1WGXz81bjEvQgbcpe5XACI3I=
-knative.dev/pkg v0.0.0-20201117221452-0fccc54273ed/go.mod h1:nxlh3CUvx6WBPr1WKD96AHxFZPD2UKRDo9RUp8ILTyQ=
+knative.dev/networking v0.0.0-20201119153452-ac0823abbb90 h1:cQtGlNyugX3N7lWR/YFYrNB1tUZUDkDSNfpLvXuIBxg=
+knative.dev/networking v0.0.0-20201119153452-ac0823abbb90/go.mod h1:nSQJwxjDMbJ2/XxzJ2KR8bg6lf6RjzH7M+3Im1T51z0=
 knative.dev/pkg v0.0.0-20201119021551-260026d54739 h1:23XBvGmbprZ86TY9HJQmO7ZKp/te3LzJdKeVX7o9TAw=
 knative.dev/pkg v0.0.0-20201119021551-260026d54739/go.mod h1:3Udj7GogdjFg0M05MJm+aJjHx1BK/tyQarl5RB2k0Xo=
 pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go
index a93e333f..717c5e21 100644
--- a/pkg/generator/generator.go
+++ b/pkg/generator/generator.go
@@ -28,14 +28,13 @@ import (
 // regenerate it. We can optimize this later.
 func UpdateInfoForIngress(ctx context.Context, caches *Caches, ing *v1alpha1.Ingress, translator *IngressTranslator, extAuthzEnabled bool) error {
 	// Adds a header with the ingress Hash and a random value header to force the config reload.
-	_, err := ingress.InsertProbe(ing)
-	if err != nil {
-		return fmt.Errorf("failed to add knative probe header in ingress: %s", ing.GetName())
+	if _, err := ingress.InsertProbe(ing); err != nil {
+		return fmt.Errorf("failed to add knative probe header: %w", err)
 	}
 
 	ingressTranslation, err := translator.translateIngress(ctx, ing, extAuthzEnabled)
 	if err != nil {
-		return err
+		return fmt.Errorf("failed to translate ingress: %w", err)
 	}
 
 	if ingressTranslation == nil {
diff --git a/pkg/generator/ingress_translator.go b/pkg/generator/ingress_translator.go
index b1eaeb13..8f2b7b49 100644
--- a/pkg/generator/ingress_translator.go
+++ b/pkg/generator/ingress_translator.go
@@ -91,7 +91,9 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 	externalHosts := make([]*route.VirtualHost, 0, len(ingress.Spec.Rules))
 	clusters := make([]*v2.Cluster, 0, len(ingress.Spec.Rules))
 
-	for _, rule := range 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))
 		for _, httpPath := range rule.HTTP.Paths {
 			// Default the path to "/" if none is passed.
@@ -100,8 +102,14 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 				path = "/"
 			}
 
+			pathName := fmt.Sprintf("%s.Paths[%s]", ruleName, path)
+
 			wrs := make([]*route.WeightedCluster_ClusterWeight, 0, len(httpPath.Splits))
 			for _, split := range httpPath.Splits {
+				// The FQN of the service is sufficient here, as clusters towards the
+				// same service are supposed to be deduplicated anyway.
+				splitName := fmt.Sprintf("%s/%s", split.ServiceNamespace, split.ServiceName)
+
 				if err := trackService(translator.tracker, split.ServiceName, ingress); err != nil {
 					return nil, err
 				}
@@ -156,18 +164,16 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 				}
 
 				connectTimeout := 5 * time.Second
-				cluster := envoy.NewCluster(split.ServiceName+path, connectTimeout, publicLbEndpoints, http2, typ)
+				cluster := envoy.NewCluster(splitName, connectTimeout, publicLbEndpoints, http2, typ)
 				clusters = append(clusters, cluster)
 
-				weightedCluster := envoy.NewWeightedCluster(split.ServiceName+path, uint32(split.Percent), split.AppendHeaders)
+				weightedCluster := envoy.NewWeightedCluster(splitName, uint32(split.Percent), split.AppendHeaders)
 				wrs = append(wrs, weightedCluster)
 			}
 
 			if len(wrs) != 0 {
-				// Note: routeName uses the non-defaulted path.
-				routeName := ingress.Name + "_" + ingress.Namespace + "_" + httpPath.Path
 				routes = append(routes, envoy.NewRoute(
-					routeName, matchHeadersFromHTTPPath(httpPath), path, wrs, 0, httpPath.AppendHeaders, httpPath.RewriteHost))
+					pathName, matchHeadersFromHTTPPath(httpPath), path, wrs, 0, httpPath.AppendHeaders, httpPath.RewriteHost))
 			}
 		}
 
@@ -182,9 +188,9 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
 				"client":     "kourier",
 				"visibility": string(rule.Visibility),
 			}, ingress.GetLabels())
-			virtualHost = envoy.NewVirtualHostWithExtAuthz(ingress.Name, contextExtensions, domainsForRule(rule), routes)
+			virtualHost = envoy.NewVirtualHostWithExtAuthz(ruleName, contextExtensions, domainsForRule(rule), routes)
 		} else {
-			virtualHost = envoy.NewVirtualHost(ingress.Name, domainsForRule(rule), routes)
+			virtualHost = envoy.NewVirtualHost(ruleName, domainsForRule(rule), routes)
 		}
 
 		internalHosts = append(internalHosts, virtualHost)
diff --git a/pkg/reconciler/ingress/ingress.go b/pkg/reconciler/ingress/ingress.go
index 21a1f542..24606d0c 100644
--- a/pkg/reconciler/ingress/ingress.go
+++ b/pkg/reconciler/ingress/ingress.go
@@ -59,9 +59,9 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, ing *v1alpha1.Ingress) r
 	}
 
 	if !ing.IsReady() {
-		ready, err := r.statusManager.IsReady(context.TODO(), before)
+		ready, err := r.statusManager.IsReady(ctx, before)
 		if err != nil {
-			return fmt.Errorf("failed to probe Ingress %s/%s: %w", ing.GetNamespace(), ing.GetName(), err)
+			return fmt.Errorf("failed to probe Ingress: %w", err)
 		}
 		if ready {
 			external, internal := config.ServiceHostnames()
@@ -95,9 +95,10 @@ func (r *Reconciler) ObserveKind(ctx context.Context, ing *v1alpha1.Ingress) rec
 func (r *Reconciler) FinalizeKind(ctx context.Context, ing *v1alpha1.Ingress) reconciler.Event {
 	return r.ObserveFinalizeKind(ctx, ing)
 }
+
 func (r *Reconciler) ObserveFinalizeKind(ctx context.Context, ing *v1alpha1.Ingress) reconciler.Event {
 	logger := logging.FromContext(ctx)
-	logger.Infof("Deleting Ingress %s/%s", ing.Name, ing.Namespace)
+	logger.Infof("Deleting Ingress")
 
 	r.statusManager.CancelIngressProbing(ing)
 
@@ -110,24 +111,20 @@ func (r *Reconciler) ObserveFinalizeKind(ctx context.Context, ing *v1alpha1.Ingr
 
 func (r *Reconciler) updateIngress(ctx context.Context, ingress *v1alpha1.Ingress) error {
 	logger := logging.FromContext(ctx)
-	logger.Infof("Updating Ingress %s namespace: %s", ingress.Name, ingress.Namespace)
+	logger.Infof("Updating Ingress")
 
 	if err := generator.UpdateInfoForIngress(
 		ctx, r.caches, ingress, r.ingressTranslator, r.extAuthz); err != nil {
 		return err
 	}
 
-	if err := r.updateEnvoyConfig(ctx); err != nil {
-		return err
-	}
-
-	return nil
+	return r.updateEnvoyConfig(ctx)
 }
 
 func (r *Reconciler) updateEnvoyConfig(ctx context.Context) error {
 	logger := logging.FromContext(ctx)
-
 	logger.Debugf("Preparing Envoy Snapshot")
+
 	newSnapshot, err := r.caches.ToEnvoySnapshot(ctx)
 	if err != nil {
 		return err
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 80dc3241..8dd35b4b 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -835,7 +835,7 @@ k8s.io/utils/trace
 # knative.dev/hack v0.0.0-20201119025252-d3cb354f49ff
 ## explicit
 knative.dev/hack
-# knative.dev/networking v0.0.0-20201119023952-faeea4d06427
+# knative.dev/networking v0.0.0-20201119153452-ac0823abbb90
 ## explicit
 knative.dev/networking/pkg
 knative.dev/networking/pkg/apis/networking


Test patch:
diff --git a/pkg/generator/ingress_translator_test.go b/pkg/generator/ingress_translator_test.go
index 6066848b..3b7de3c9 100644
--- a/pkg/generator/ingress_translator_test.go
+++ b/pkg/generator/ingress_translator_test.go
@@ -53,10 +53,10 @@ func TestIngressTranslator(t *testing.T) {
 		want: func() *translatedIngress {
 			vHosts := []*route.VirtualHost{
 				envoy.NewVirtualHost(
-					"simplename",
+					"(simplens/simplename).Rules[0]",
 					[]string{"foo.example.com", "foo.example.com:*"},
 					[]*route.Route{envoy.NewRoute(
-						"simplename_simplens_/test",
+						"(simplens/simplename).Rules[0].Paths[/test]",
 						[]*route.HeaderMatcher{{
 							Name: "testheader",
 							HeaderMatchSpecifier: &route.HeaderMatcher_ExactMatch{
@@ -65,7 +65,7 @@ func TestIngressTranslator(t *testing.T) {
 						}},
 						"/test",
 						[]*route.WeightedCluster_ClusterWeight{
-							envoy.NewWeightedCluster("servicename/test", 100, map[string]string{"baz": "gna"}),
+							envoy.NewWeightedCluster("servicens/servicename", 100, map[string]string{"baz": "gna"}),
 						},
 						0,
 						map[string]string{"foo": "bar"},
@@ -82,7 +82,7 @@ func TestIngressTranslator(t *testing.T) {
 				sniMatches: []*envoy.SNIMatch{},
 				clusters: []*v2.Cluster{
 					envoy.NewCluster(
-						"servicename/test",
+						"servicens/servicename",
 						5*time.Second,
 						lbEndpoints,
 						false,
@@ -110,10 +110,10 @@ func TestIngressTranslator(t *testing.T) {
 		want: func() *translatedIngress {
 			vHosts := []*route.VirtualHost{
 				envoy.NewVirtualHost(
-					"testname",
+					"(testspace/testname).Rules[0]",
 					[]string{"foo.example.com", "foo.example.com:*"},
 					[]*route.Route{envoy.NewRoute(
-						"testname_testspace_/test",
+						"(testspace/testname).Rules[0].Paths[/test]",
 						[]*route.HeaderMatcher{{
 							Name: "testheader",
 							HeaderMatchSpecifier: &route.HeaderMatcher_ExactMatch{
@@ -122,7 +122,7 @@ func TestIngressTranslator(t *testing.T) {
 						}},
 						"/test",
 						[]*route.WeightedCluster_ClusterWeight{
-							envoy.NewWeightedCluster("servicename/test", 100, map[string]string{"baz": "gna"}),
+							envoy.NewWeightedCluster("servicens/servicename", 100, map[string]string{"baz": "gna"}),
 						},
 						0,
 						map[string]string{"foo": "bar"},
@@ -147,7 +147,7 @@ func TestIngressTranslator(t *testing.T) {
 				}},
 				clusters: []*v2.Cluster{
 					envoy.NewCluster(
-						"servicename/test",
+						"servicens/servicename",
 						5*time.Second,
 						lbEndpoints,
 						false,
@@ -192,10 +192,10 @@ func TestIngressTranslator(t *testing.T) {
 		want: func() *translatedIngress {
 			vHosts := []*route.VirtualHost{
 				envoy.NewVirtualHost(
-					"testname",
+					"(testspace/testname).Rules[0]",
 					[]string{"foo.example.com", "foo.example.com:*"},
 					[]*route.Route{envoy.NewRoute(
-						"testname_testspace_/test",
+						"(testspace/testname).Rules[0].Paths[/test]",
 						[]*route.HeaderMatcher{{
 							Name: "testheader",
 							HeaderMatchSpecifier: &route.HeaderMatcher_ExactMatch{
@@ -204,9 +204,9 @@ func TestIngressTranslator(t *testing.T) {
 						}},
 						"/test",
 						[]*route.WeightedCluster_ClusterWeight{
-							envoy.NewWeightedCluster("servicename/test", 33, map[string]string{"baz": "gna"}),
-							envoy.NewWeightedCluster("servicename2/test", 33, nil),
-							envoy.NewWeightedCluster("servicename3/test", 34, nil),
+							envoy.NewWeightedCluster("servicens/servicename", 33, map[string]string{"baz": "gna"}),
+							envoy.NewWeightedCluster("servicens2/servicename2", 33, nil),
+							envoy.NewWeightedCluster("servicens3/servicename3", 34, nil),
 						},
 						0,
 						map[string]string{"foo": "bar"},
@@ -223,21 +223,21 @@ func TestIngressTranslator(t *testing.T) {
 				sniMatches: []*envoy.SNIMatch{},
 				clusters: []*v2.Cluster{
 					envoy.NewCluster(
-						"servicename/test",
+						"servicens/servicename",
 						5*time.Second,
 						lbEndpoints,
 						false,
 						v2.Cluster_STATIC,
 					),
 					envoy.NewCluster(
-						"servicename2/test",
+						"servicens2/servicename2",
 						5*time.Second,
 						lbEndpoints,
 						false,
 						v2.Cluster_STATIC,
 					),
 					envoy.NewCluster(
-						"servicename3/test",
+						"servicens3/servicename3",
 						5*time.Second,
 						[]*endpoint.LbEndpoint{envoy.NewLBEndpoint("example.com", 80)},
 						false,
@@ -260,10 +260,10 @@ func TestIngressTranslator(t *testing.T) {
 		want: func() *translatedIngress {
 			vHosts := []*route.VirtualHost{
 				envoy.NewVirtualHost(
-					"testname",
+					"(testspace/testname).Rules[0]",
 					[]string{"foo.example.com", "foo.example.com:*"},
 					[]*route.Route{envoy.NewRoute(
-						"testname_testspace_",
+						"(testspace/testname).Rules[0].Paths[/]",
 						[]*route.HeaderMatcher{{
 							Name: "testheader",
 							HeaderMatchSpecifier: &route.HeaderMatcher_ExactMatch{
@@ -272,7 +272,7 @@ func TestIngressTranslator(t *testing.T) {
 						}},
 						"/",
 						[]*route.WeightedCluster_ClusterWeight{
-							envoy.NewWeightedCluster("servicename/", 100, map[string]string{"baz": "gna"}),
+							envoy.NewWeightedCluster("servicens/servicename", 100, map[string]string{"baz": "gna"}),
 						},
 						0,
 						map[string]string{"foo": "bar"},
@@ -289,7 +289,7 @@ func TestIngressTranslator(t *testing.T) {
 				sniMatches: []*envoy.SNIMatch{},
 				clusters: []*v2.Cluster{
 					envoy.NewCluster(
-						"servicename/",
+						"servicens/servicename",
 						5*time.Second,
 						lbEndpoints,
 						false,
@@ -312,10 +312,10 @@ func TestIngressTranslator(t *testing.T) {
 		want: func() *translatedIngress {
 			vHosts := []*route.VirtualHost{
 				envoy.NewVirtualHost(
-					"testname",
+					"(testspace/testname).Rules[0]",
 					[]string{"foo.example.com", "foo.example.com:*"},
 					[]*route.Route{envoy.NewRoute(
-						"testname_testspace_/test",
+						"(testspace/testname).Rules[0].Paths[/test]",
 						[]*route.HeaderMatcher{{
 							Name: "testheader",
 							HeaderMatchSpecifier: &route.HeaderMatcher_ExactMatch{
@@ -324,7 +324,7 @@ func TestIngressTranslator(t *testing.T) {
 						}},
 						"/test",
 						[]*route.WeightedCluster_ClusterWeight{
-							envoy.NewWeightedCluster("servicename/test", 100, map[string]string{"baz": "gna"}),
+							envoy.NewWeightedCluster("servicens/servicename", 100, map[string]string{"baz": "gna"}),
 						},
 						0,
 						map[string]string{"foo": "bar"},
@@ -341,7 +341,7 @@ func TestIngressTranslator(t *testing.T) {
 				sniMatches: []*envoy.SNIMatch{},
 				clusters: []*v2.Cluster{
 					envoy.NewCluster(
-						"servicename/test",
+						"servicens/servicename",
 						5*time.Second,
 						[]*endpoint.LbEndpoint{envoy.NewLBEndpoint("example.com", 80)},
 						false,
diff --git a/vendor/knative.dev/networking/test/conformance/ingress/rule.go b/vendor/knative.dev/networking/test/conformance/ingress/rule.go
new file mode 100644
index 00000000..9a1ae81c
--- /dev/null
+++ b/vendor/knative.dev/networking/test/conformance/ingress/rule.go
@@ -0,0 +1,71 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package ingress
+
+import (
+	"context"
+	"testing"
+
+	"k8s.io/apimachinery/pkg/util/intstr"
+	"knative.dev/networking/pkg/apis/networking"
+	"knative.dev/networking/pkg/apis/networking/v1alpha1"
+	"knative.dev/networking/test"
+)
+
+// TestRule verifies that an Ingress properly dispatches to backends based on different rules.
+func TestRule(t *testing.T) {
+	t.Parallel()
+	ctx, clients := context.Background(), test.Setup(t)
+
+	fooName, fooPort, _ := CreateRuntimeService(ctx, t, clients, networking.ServicePortNameHTTP1)
+	barName, barPort, _ := CreateRuntimeService(ctx, t, clients, networking.ServicePortNameHTTP1)
+
+	_, client, _ := CreateIngressReady(ctx, t, clients, v1alpha1.IngressSpec{
+		Rules: []v1alpha1.IngressRule{{
+			Hosts:      []string{fooName + ".example.com"},
+			Visibility: v1alpha1.IngressVisibilityExternalIP,
+			HTTP: &v1alpha1.HTTPIngressRuleValue{
+				Paths: []v1alpha1.HTTPIngressPath{{
+					Splits: []v1alpha1.IngressBackendSplit{{
+						IngressBackend: v1alpha1.IngressBackend{
+							ServiceName:      fooName,
+							ServiceNamespace: test.ServingNamespace,
+							ServicePort:      intstr.FromInt(fooPort),
+						},
+					}},
+				}},
+			},
+		}, {
+			Hosts:      []string{barName + ".example.com"},
+			Visibility: v1alpha1.IngressVisibilityExternalIP,
+			HTTP: &v1alpha1.HTTPIngressRuleValue{
+				Paths: []v1alpha1.HTTPIngressPath{{
+					Splits: []v1alpha1.IngressBackendSplit{{
+						IngressBackend: v1alpha1.IngressBackend{
+							ServiceName:      barName,
+							ServiceNamespace: test.ServingNamespace,
+							ServicePort:      intstr.FromInt(barPort),
+						},
+					}},
+				}},
+			},
+		}},
+	})
+
+	RuntimeRequest(ctx, t, client, "http://"+fooName+".example.com")
+	RuntimeRequest(ctx, t, client, "http://"+barName+".example.com")
+}
diff --git a/vendor/knative.dev/networking/test/conformance/ingress/run.go b/vendor/knative.dev/networking/test/conformance/ingress/run.go
index 87df33ed..edcfc30d 100644
--- a/vendor/knative.dev/networking/test/conformance/ingress/run.go
+++ b/vendor/knative.dev/networking/test/conformance/ingress/run.go
@@ -34,6 +34,7 @@ var stableTests = map[string]func(t *testing.T){
 	"dispatch/path":                TestPath,
 	"dispatch/percentage":          TestPercentage,
 	"dispatch/path_and_percentage": TestPathAndPercentageSplit,
+	"dispatch/rule":                TestRule,
 	"timeout":                      TestTimeout,
 	"tls":                          TestIngressTLS,
 	"update":                       TestUpdate,