Repository: envoyproxy/gateway
Pull request #4207 (2024-09-10 19:32:05)

release: v1.1.1
**What type of PR is this?**
<!--
Your PR title should be descriptive, and generally start with type that contains a subsystem name with `()` if necessary 
and summary followed by a colon. format `chore/docs/api/feat/fix/refactor/style/test: summary`.
Examples:
* "docs: fix grammar error"
* "feat(translator): add new feature"
* "fix: fix xx bug"
* "chore: change ci & build tools etc"
* "api: add xxx fields in ClientTrafficPolicy"
-->

<!--
NOTE: If your PR contains any API changes (changes under `/api`), we recommend you to separate these API changes into
a new PR, and we will review the API part first. It will save you lots of implementation time if the API get accepted.
-->

**What this PR does / why we need it**:

**Which issue(s) this PR fixes**:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
v1.1.1

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/4207?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 67.97%. Comparing base [(`75fa107`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/75fa107d3d985ced40dc777a9118909938cfe230?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`f0f5eca`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/f0f5eca2bc7e3feccd5b48dfbc9ce6617c89d992?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #4207      +/-   ##
==========================================
- Coverage   67.98%   67.97%   -0.02%     
==========================================
  Files         190      190              
  Lines       23127    23127              
==========================================
- Hits        15724    15720       -4     
- Misses       6284     6287       +3     
- Partials     1119     1120       +1     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/4207?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).

guydc: /retest

Patch:
diff --git a/VERSION b/VERSION
index 795460fce..56130fb3a 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-v1.1.0
+v1.1.1
diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go
index eba70f967..651e16352 100644
--- a/internal/gatewayapi/runner/runner.go
+++ b/internal/gatewayapi/runner/runner.go
@@ -263,6 +263,13 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
 					}
 					delete(statusesToDelete.EnvoyExtensionPolicyStatusKeys, key)
 				}
+				for _, backend := range result.Backends {
+					key := utils.NamespacedName(backend)
+					if !(reflect.ValueOf(backend.Status).IsZero()) {
+						r.ProviderResources.BackendStatuses.Store(key, &backend.Status)
+					}
+					delete(statusesToDelete.BackendStatusKeys, key)
+				}
 				for _, extServerPolicy := range result.ExtensionServerPolicies {
 					key := message.NamespacedNameAndGVK{
 						NamespacedName:   utils.NamespacedName(&extServerPolicy),
@@ -323,6 +330,8 @@ type StatusesToDelete struct {
 	SecurityPolicyStatusKeys        map[types.NamespacedName]bool
 	EnvoyExtensionPolicyStatusKeys  map[types.NamespacedName]bool
 	ExtensionServerPolicyStatusKeys map[message.NamespacedNameAndGVK]bool
+
+	BackendStatusKeys map[types.NamespacedName]bool
 }
 
 func (r *Runner) getAllStatuses() *StatusesToDelete {
@@ -341,6 +350,8 @@ func (r *Runner) getAllStatuses() *StatusesToDelete {
 		BackendTLSPolicyStatusKeys:      make(map[types.NamespacedName]bool),
 		EnvoyExtensionPolicyStatusKeys:  make(map[types.NamespacedName]bool),
 		ExtensionServerPolicyStatusKeys: make(map[message.NamespacedNameAndGVK]bool),
+
+		BackendStatusKeys: make(map[types.NamespacedName]bool),
 	}
 
 	// Get current status keys
@@ -378,6 +389,9 @@ func (r *Runner) getAllStatuses() *StatusesToDelete {
 	for key := range r.ProviderResources.EnvoyExtensionPolicyStatuses.LoadAll() {
 		ds.EnvoyExtensionPolicyStatusKeys[key] = true
 	}
+	for key := range r.ProviderResources.BackendStatuses.LoadAll() {
+		ds.BackendStatusKeys[key] = true
+	}
 	return ds
 }
 
@@ -431,6 +445,10 @@ func (r *Runner) deleteStatusKeys(ds *StatusesToDelete) {
 		r.ProviderResources.ExtensionPolicyStatuses.Delete(key)
 		delete(ds.ExtensionServerPolicyStatusKeys, key)
 	}
+	for key := range ds.BackendStatusKeys {
+		r.ProviderResources.BackendStatuses.Delete(key)
+		delete(ds.BackendStatusKeys, key)
+	}
 }
 
 // deleteAllStatusKeys deletes all status keys stored by the subscriber.
@@ -474,6 +492,9 @@ func (r *Runner) deleteAllStatusKeys() {
 	for key := range r.ProviderResources.ExtensionPolicyStatuses.LoadAll() {
 		r.ProviderResources.ExtensionPolicyStatuses.Delete(key)
 	}
+	for key := range r.ProviderResources.BackendStatuses.LoadAll() {
+		r.ProviderResources.BackendStatuses.Delete(key)
+	}
 }
 
 // getIRKeysToDelete returns the list of IR keys to delete
diff --git a/internal/gatewayapi/status/backend.go b/internal/gatewayapi/status/backend.go
index 7b841baaa..16c0139ca 100644
--- a/internal/gatewayapi/status/backend.go
+++ b/internal/gatewayapi/status/backend.go
@@ -31,11 +31,11 @@ func UpdateBackendStatusAcceptedCondition(be *egv1a1.Backend, accepted bool, msg
 func computeBackendAcceptedCondition(be *egv1a1.Backend, accepted bool, msg string) metav1.Condition {
 	switch accepted {
 	case true:
-		return newCondition(string(egv1a1.BackendReasonInvalid), metav1.ConditionTrue,
+		return newCondition(string(egv1a1.BackendReasonAccepted), metav1.ConditionTrue,
 			string(egv1a1.BackendConditionAccepted),
 			"The Backend was accepted", time.Now(), be.Generation)
 	default:
-		return newCondition(string(egv1a1.BackendReasonAccepted), metav1.ConditionFalse,
+		return newCondition(string(egv1a1.BackendReasonInvalid), metav1.ConditionFalse,
 			string(egv1a1.BackendConditionAccepted),
 			msg, time.Now(), be.Generation)
 	}
diff --git a/internal/message/types.go b/internal/message/types.go
index fb82aa140..6a39685a8 100644
--- a/internal/message/types.go
+++ b/internal/message/types.go
@@ -12,6 +12,7 @@ import (
 	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
 	gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
 
+	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/gatewayapi"
 	"github.com/envoyproxy/gateway/internal/ir"
 	xdstypes "github.com/envoyproxy/gateway/internal/xds/types"
@@ -29,6 +30,9 @@ type ProviderResources struct {
 
 	// PolicyStatuses is a group of policy statuses maps.
 	PolicyStatuses
+
+	// ExtensionStatuses is a group of gw-api extension resource statuses map.
+	ExtensionStatuses
 }
 
 func (p *ProviderResources) GetResources() []*gatewayapi.Resources {
@@ -104,6 +108,11 @@ type PolicyStatuses struct {
 	ExtensionPolicyStatuses      watchable.Map[NamespacedNameAndGVK, *gwapiv1a2.PolicyStatus]
 }
 
+// ExtensionStatuses contains statuses related to gw-api extension resources
+type ExtensionStatuses struct {
+	BackendStatuses watchable.Map[types.NamespacedName, *egv1a1.BackendStatus]
+}
+
 func (p *PolicyStatuses) Close() {
 	p.ClientTrafficPolicyStatuses.Close()
 	p.SecurityPolicyStatuses.Close()
diff --git a/internal/provider/kubernetes/status.go b/internal/provider/kubernetes/status.go
index 85e9ff993..c94ad2bc5 100644
--- a/internal/provider/kubernetes/status.go
+++ b/internal/provider/kubernetes/status.go
@@ -399,6 +399,38 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
 		r.log.Info("envoyExtensionPolicy status subscriber shutting down")
 	}()
 
+	// Backend object status updater
+	go func() {
+		message.HandleSubscription(
+			message.Metadata{Runner: string(egv1a1.LogComponentProviderRunner), Message: "backend-status"},
+			r.resources.BackendStatuses.Subscribe(ctx),
+			func(update message.Update[types.NamespacedName, *egv1a1.BackendStatus], errChan chan error) {
+				// skip delete updates.
+				if update.Delete {
+					return
+				}
+				key := update.Key
+				val := update.Value
+				r.statusUpdater.Send(Update{
+					NamespacedName: key,
+					Resource:       new(egv1a1.Backend),
+					Mutator: MutatorFunc(func(obj client.Object) client.Object {
+						t, ok := obj.(*egv1a1.Backend)
+						if !ok {
+							err := fmt.Errorf("unsupported object type %T", obj)
+							errChan <- err
+							panic(err)
+						}
+						tCopy := t.DeepCopy()
+						tCopy.Status = *val
+						return tCopy
+					}),
+				})
+			},
+		)
+		r.log.Info("backend status subscriber shutting down")
+	}()
+
 	if extensionManagerEnabled {
 		// EnvoyExtensionPolicy object status updater
 		go func() {
diff --git a/release-notes/v1.1.1.yaml b/release-notes/v1.1.1.yaml
new file mode 100644
index 000000000..ac5f40ea6
--- /dev/null
+++ b/release-notes/v1.1.1.yaml
@@ -0,0 +1,42 @@
+date: September 11, 2024
+
+changes:
+  - area: documentation
+    change: |
+      Bumped Golang version to 1.22.7
+
+
+  - area: conformance
+    change: |
+      Enabled GatewayHTTPListenerIsolation test
+
+
+  - area: testing
+    change: |
+      Fix download URL of envoy proxy WASM examples used in tests
+
+
+  - area: translator
+    change: |
+      Fixed url rewrite to remove trailing slash
+      Isolate HTTP route tables to listener according to Gateway-API specifications
+      Fixed identification of ReferenceGrant when multiple ReferenceGrants exist in a namespace
+      Fixed added header values as a command and space delimited list
+      Fixed assertion on expected status in active HTTP healthcheck
+      Fixed rejection of invalid Backends referenced by xRoutes
+      Fixed support for empty SlowStart configuration when using LeastRequest loadbalancing
+      Fixed update of status for Backends
+
+
+  - area: infra-manager
+    change: |
+      Pin ratelimit version to 26f28d78
+      Reduce readinessProbe failureThreshold and periodSeconds of proxy
+      Expose ratelimit statsd
+
+
+  - area: providers
+    change: |
+      Fixed error returned when referenced Configmap or Secret is not found
+      Use component name in Envoy Gateway logs
+
diff --git a/site/content/en/news/releases/notes/v1.1.1.md b/site/content/en/news/releases/notes/v1.1.1.md
new file mode 100644
index 000000000..5f5cda1c1
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.1.1.md
@@ -0,0 +1,35 @@
+---
+title: "v1.1.1"
+publishdate: 2024-09-11
+---
+
+Date: September 11, 2024
+
+## Documentation
+- Bumped Golang version to 1.22.7
+
+## Conformance
+- Enabled GatewayHTTPListenerIsolation test
+
+## Testing
+- Fix download URL of envoy proxy WASM examples used in tests
+
+## Translator
+- Fixed url rewrite to remove trailing slash
+- Isolate HTTP route tables to listener according to Gateway-API specifications
+- Fixed identification of ReferenceGrant when multiple ReferenceGrants exist in a namespace
+- Fixed added header values as a command and space delimited list
+- Fixed assertion on expected status in active HTTP healthcheck
+- Fixed rejection of invalid Backends referenced by xRoutes
+- Fixed support for empty SlowStart configuration when using LeastRequest loadbalancing
+- Fixed update of status for Backends
+
+## Infra-manager
+- Pin ratelimit version to 26f28d78
+- Reduce readinessProbe failureThreshold and periodSeconds of proxy
+- Expose ratelimit statsd
+
+## Providers
+- Fixed error returned when referenced Configmap or Secret is not found
+- Use component name in Envoy Gateway logs
+


Test patch:
diff --git a/internal/gatewayapi/runner/runner_test.go b/internal/gatewayapi/runner/runner_test.go
index 502a96950..58515da7e 100644
--- a/internal/gatewayapi/runner/runner_test.go
+++ b/internal/gatewayapi/runner/runner_test.go
@@ -164,6 +164,10 @@ func TestDeleteStatusKeys(t *testing.T) {
 			Name:      "test7",
 			Namespace: "test-namespace",
 		},
+		{
+			Name:      "test8",
+			Namespace: "test-namespace",
+		},
 	}
 
 	r.ProviderResources.GatewayStatuses.Store(keys[0], &gwapiv1.GatewayStatus{})
@@ -173,6 +177,7 @@ func TestDeleteStatusKeys(t *testing.T) {
 	r.ProviderResources.TCPRouteStatuses.Store(keys[4], &gwapiv1a2.TCPRouteStatus{})
 	r.ProviderResources.UDPRouteStatuses.Store(keys[5], &gwapiv1a2.UDPRouteStatus{})
 	r.ProviderResources.UDPRouteStatuses.Store(keys[6], &gwapiv1a2.UDPRouteStatus{})
+	r.ProviderResources.BackendStatuses.Store(keys[7], &egv1a1.BackendStatus{})
 
 	// Checks that the keys are successfully stored to DeletableStatus and watchable maps
 	ds := r.getAllStatuses()
@@ -184,6 +189,7 @@ func TestDeleteStatusKeys(t *testing.T) {
 	require.True(t, ds.TCPRouteStatusKeys[keys[4]])
 	require.True(t, ds.UDPRouteStatusKeys[keys[5]])
 	require.True(t, ds.UDPRouteStatusKeys[keys[6]])
+	require.True(t, ds.BackendStatusKeys[keys[7]])
 
 	require.Equal(t, 1, r.ProviderResources.GatewayStatuses.Len())
 	require.Equal(t, 1, r.ProviderResources.HTTPRouteStatuses.Len())
@@ -191,6 +197,7 @@ func TestDeleteStatusKeys(t *testing.T) {
 	require.Equal(t, 1, r.ProviderResources.TLSRouteStatuses.Len())
 	require.Equal(t, 1, r.ProviderResources.TCPRouteStatuses.Len())
 	require.Equal(t, 2, r.ProviderResources.UDPRouteStatuses.Len())
+	require.Equal(t, 1, r.ProviderResources.BackendStatuses.Len())
 
 	// Delete all keys except the last UDPRouteStatus key
 	delete(ds.UDPRouteStatusKeys, keys[6])
@@ -202,6 +209,7 @@ func TestDeleteStatusKeys(t *testing.T) {
 	require.Equal(t, 0, r.ProviderResources.TLSRouteStatuses.Len())
 	require.Equal(t, 0, r.ProviderResources.TCPRouteStatuses.Len())
 	require.Equal(t, 1, r.ProviderResources.UDPRouteStatuses.Len())
+	require.Equal(t, 0, r.ProviderResources.BackendStatuses.Len())
 }
 
 func TestDeleteAllStatusKeys(t *testing.T) {
@@ -253,6 +261,10 @@ func TestDeleteAllStatusKeys(t *testing.T) {
 			Name:      "test6",
 			Namespace: "test-namespace",
 		},
+		{
+			Name:      "test7",
+			Namespace: "test-namespace",
+		},
 	}
 
 	r.ProviderResources.GatewayStatuses.Store(keys[0], &gwapiv1.GatewayStatus{})
@@ -261,6 +273,7 @@ func TestDeleteAllStatusKeys(t *testing.T) {
 	r.ProviderResources.TLSRouteStatuses.Store(keys[3], &gwapiv1a2.TLSRouteStatus{})
 	r.ProviderResources.TCPRouteStatuses.Store(keys[4], &gwapiv1a2.TCPRouteStatus{})
 	r.ProviderResources.UDPRouteStatuses.Store(keys[5], &gwapiv1a2.UDPRouteStatus{})
+	r.ProviderResources.BackendStatuses.Store(keys[6], &egv1a1.BackendStatus{})
 
 	// Checks that the keys are successfully stored to DeletableStatus and watchable maps
 	ds := r.getAllStatuses()
@@ -271,6 +284,7 @@ func TestDeleteAllStatusKeys(t *testing.T) {
 	require.True(t, ds.TLSRouteStatusKeys[keys[3]])
 	require.True(t, ds.TCPRouteStatusKeys[keys[4]])
 	require.True(t, ds.UDPRouteStatusKeys[keys[5]])
+	require.True(t, ds.BackendStatusKeys[keys[6]])
 
 	require.Equal(t, 1, r.ProviderResources.GatewayStatuses.Len())
 	require.Equal(t, 1, r.ProviderResources.HTTPRouteStatuses.Len())
@@ -278,6 +292,7 @@ func TestDeleteAllStatusKeys(t *testing.T) {
 	require.Equal(t, 1, r.ProviderResources.TLSRouteStatuses.Len())
 	require.Equal(t, 1, r.ProviderResources.TCPRouteStatuses.Len())
 	require.Equal(t, 1, r.ProviderResources.UDPRouteStatuses.Len())
+	require.Equal(t, 1, r.ProviderResources.BackendStatuses.Len())
 
 	// Delete all keys
 	r.deleteAllStatusKeys()
@@ -287,4 +302,5 @@ func TestDeleteAllStatusKeys(t *testing.T) {
 	require.Equal(t, 0, r.ProviderResources.TLSRouteStatuses.Len())
 	require.Equal(t, 0, r.ProviderResources.TCPRouteStatuses.Len())
 	require.Equal(t, 0, r.ProviderResources.UDPRouteStatuses.Len())
+	require.Equal(t, 0, r.ProviderResources.BackendStatuses.Len())
 }
diff --git a/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
index c1425425b..49d35c607 100644
--- a/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
+++ b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
@@ -17,7 +17,7 @@ backends:
         Gateway Config
       reason: Accepted
       status: "False"
-      type: Accepted
+      type: Invalid
 envoyExtensionPolicies:
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: EnvoyExtensionPolicy
diff --git a/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml b/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
index e917d9cb2..0c022cc4c 100644
--- a/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
+++ b/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
@@ -16,7 +16,7 @@ backends:
       message: 'The Backend was not accepted: hostname *.foo.com is not a valid FQDN'
       reason: Accepted
       status: "False"
-      type: Accepted
+      type: Invalid
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -35,7 +35,7 @@ backends:
         with at least two segments separated by dots'
       reason: Accepted
       status: "False"
-      type: Accepted
+      type: Invalid
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -54,7 +54,7 @@ backends:
         range is not supported'
       reason: Accepted
       status: "False"
-      type: Accepted
+      type: Invalid
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -72,6 +72,6 @@ backends:
       message: 'The Backend was not accepted: IP address example.com is invalid'
       reason: Accepted
       status: "False"
-      type: Accepted
+      type: Invalid
 infraIR: {}
 xdsIR: {}
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
index 6f82b206f..5791f6071 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
@@ -62,7 +62,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
index cf416e972..66dfad1a1 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
@@ -78,7 +78,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
index fda8a8185..b8b810a3d 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
@@ -80,7 +80,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -98,7 +98,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 envoyExtensionPolicies:
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: EnvoyExtensionPolicy
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml
index 17f9e8c15..bae507b4d 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml
@@ -80,7 +80,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -98,7 +98,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 envoyExtensionPolicies:
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: EnvoyExtensionPolicy
diff --git a/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml
index 33ee92402..cdb84b469 100644
--- a/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml
@@ -80,7 +80,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -98,7 +98,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 envoyExtensionPolicies:
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: EnvoyExtensionPolicy
diff --git a/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
index 12bc6d3e1..ba9f13c31 100644
--- a/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
+++ b/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
@@ -16,7 +16,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
index 735622c40..484fe1191 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
@@ -15,7 +15,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -33,7 +33,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -51,7 +51,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
index c93f3cbe7..80b6f6627 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
@@ -18,7 +18,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -38,7 +38,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -59,7 +59,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -80,7 +80,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
index 25ee9e8ba..cdbbe7880 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
@@ -15,7 +15,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -33,7 +33,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -51,7 +51,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -70,7 +70,7 @@ backends:
         range is not supported'
       reason: Accepted
       status: "False"
-      type: Accepted
+      type: Invalid
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -89,7 +89,7 @@ backends:
         with at least two segments separated by dots'
       reason: Accepted
       status: "False"
-      type: Accepted
+      type: Invalid
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
index 68dd07112..3b5ddfa62 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
@@ -15,7 +15,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -33,7 +33,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -51,7 +51,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
index 7f4812475..5a413ae46 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
@@ -15,7 +15,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -33,7 +33,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -51,7 +51,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -68,7 +68,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -86,7 +86,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -104,7 +104,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
index c02aa5200..4c5fcd5e8 100644
--- a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
@@ -18,7 +18,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -38,7 +38,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
index 195f13d09..d56407b0d 100644
--- a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
@@ -16,7 +16,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
@@ -34,7 +34,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
index 2957475fb..05086bae4 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
@@ -16,7 +16,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
index bc18a9b53..94012ec73 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
@@ -16,7 +16,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml b/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
index c82e53e39..29a124844 100644
--- a/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
+++ b/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
@@ -16,7 +16,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
index f5839c370..13c3ef41c 100644
--- a/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
+++ b/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
@@ -16,7 +16,7 @@ backends:
       message: The Backend was accepted
       reason: Accepted
       status: "True"
-      type: Invalid
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
diff --git a/test/e2e/tests/route_with_backend.go b/test/e2e/tests/route_with_backend.go
index fadb195c3..692764cca 100644
--- a/test/e2e/tests/route_with_backend.go
+++ b/test/e2e/tests/route_with_backend.go
@@ -36,6 +36,7 @@ var EnvoyGatewayBackendTest = suite.ConformanceTest{
 			routeNN := types.NamespacedName{Name: "httproute-to-backend-fqdn", Namespace: ns}
 			gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
 			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			BackendMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "backend-fqdn", Namespace: ns})
 
 			expectedResponse := http.ExpectedResponse{
 				Request: http.Request{
@@ -55,6 +56,7 @@ var EnvoyGatewayBackendTest = suite.ConformanceTest{
 			routeNN := types.NamespacedName{Name: "httproute-to-backend-ip", Namespace: ns}
 			gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
 			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			BackendMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "backend-ip", Namespace: ns})
 
 			expectedResponse := http.ExpectedResponse{
 				Request: http.Request{
@@ -74,6 +76,7 @@ var EnvoyGatewayBackendTest = suite.ConformanceTest{
 			routeNN := types.NamespacedName{Name: "httproute-to-backend-fqdn-http2", Namespace: ns}
 			gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
 			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			BackendMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "backend-fqdn-http2", Namespace: ns})
 
 			expectedResponse := http.ExpectedResponse{
 				Request: http.Request{
@@ -93,6 +96,7 @@ var EnvoyGatewayBackendTest = suite.ConformanceTest{
 			routeNN := types.NamespacedName{Name: "httproute-to-fqdn-backend-tls", Namespace: ns}
 			gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
 			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			BackendMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "backend-fqdn-tls", Namespace: ns})
 
 			expectedResponse := http.ExpectedResponse{
 				Request: http.Request{
diff --git a/test/e2e/tests/utils.go b/test/e2e/tests/utils.go
index 8da772851..e6c6ed85c 100644
--- a/test/e2e/tests/utils.go
+++ b/test/e2e/tests/utils.go
@@ -336,6 +336,30 @@ func EnvoyExtensionPolicyMustBeAccepted(t *testing.T, client client.Client, poli
 	require.NoErrorf(t, waitErr, "error waiting for EnvoyExtensionPolicy to be accepted")
 }
 
+// BackendMustBeAccepted waits for the specified Backend to be accepted.
+func BackendMustBeAccepted(t *testing.T, client client.Client, backendName types.NamespacedName) {
+	t.Helper()
+
+	waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 60*time.Second, true, func(ctx context.Context) (bool, error) {
+		backend := &egv1a1.Backend{}
+		err := client.Get(ctx, backendName, backend)
+		if err != nil {
+			return false, fmt.Errorf("error fetching Backend: %w", err)
+		}
+
+		for _, condition := range backend.Status.Conditions {
+			if condition.Type == string(egv1a1.BackendConditionAccepted) && condition.Status == metav1.ConditionTrue {
+				return true, nil
+			}
+		}
+
+		tlog.Logf(t, "Backend not yet accepted: %v", backend)
+		return false, nil
+	})
+
+	require.NoErrorf(t, waitErr, "error waiting for Backend to be accepted")
+}
+
 func ScrapeMetrics(t *testing.T, c client.Client, nn types.NamespacedName, port int32, path string) error {
 	url, err := RetrieveURL(c, nn, port, path)
 	if err != nil {