Repository: envoyproxy/gateway
Pull request #5569: infra: delete resource if exists when using customized name
Author: login: zirain
Created: 2025-03-21T06:00:45Z | Merged: 2025-03-28T16:51:01Z

fixes: https://github.com/envoyproxy/gateway/issues/4380


Diff:
diff --git a/internal/infrastructure/kubernetes/infra.go b/internal/infrastructure/kubernetes/infra.go
index a0615a4e84..82d51d0665 100644
--- a/internal/infrastructure/kubernetes/infra.go
+++ b/internal/infrastructure/kubernetes/infra.go
@@ -20,6 +20,7 @@ import (
 	"github.com/envoyproxy/gateway/internal/envoygateway/config"
 	"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
 	"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
+	"github.com/envoyproxy/gateway/internal/logging"
 )
 
 var _ ResourceRender = &proxy.ResourceRender{}
@@ -58,6 +59,8 @@ type Infra struct {
 
 	// Client wrap k8s client.
 	Client *InfraClient
+
+	logger logging.Logger
 }
 
 // NewInfra returns a new Infra.
@@ -67,6 +70,7 @@ func NewInfra(cli client.Client, cfg *config.Server) *Infra {
 		DNSDomain:    cfg.DNSDomain,
 		EnvoyGateway: cfg.EnvoyGateway,
 		Client:       New(cli),
+		logger:       cfg.Logger.WithName(string(egv1a1.LogComponentInfrastructureRunner)),
 	}
 }
 
diff --git a/internal/infrastructure/kubernetes/infra_client.go b/internal/infrastructure/kubernetes/infra_client.go
index 0d3a01e5da..2cee236044 100644
--- a/internal/infrastructure/kubernetes/infra_client.go
+++ b/internal/infrastructure/kubernetes/infra_client.go
@@ -8,6 +8,7 @@ package kubernetes
 import (
 	"context"
 	"fmt"
+	"reflect"
 
 	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/types"
@@ -33,6 +34,41 @@ func (cli *InfraClient) ServerSideApply(ctx context.Context, obj client.Object)
 	return nil
 }
 
+// DeleteAllExcept delete all resources filter by ListOption except the one specified by key.
+func (cli *InfraClient) DeleteAllExcept(ctx context.Context, objList client.ObjectList, key client.ObjectKey, listOpts ...client.ListOption) error {
+	if err := cli.List(ctx, objList, listOpts...); err != nil {
+		if kerrors.IsNotFound(err) {
+			return nil
+		}
+		return err
+	}
+
+	v := reflect.ValueOf(objList).Elem()
+	items := v.FieldByName("Items")
+
+	// If there is only one item, we don't need to delete it,
+	// because it normally means custom resource name is not enabled.
+	if items.Len() <= 1 {
+		return nil
+	}
+
+	for i := range items.Len() {
+		item := items.Index(i)
+		name := item.FieldByName("Name")
+		namespace := item.FieldByName("Namespace")
+
+		if name.String() == key.Name && namespace.String() == key.Namespace {
+			continue
+		}
+
+		if err := cli.Delete(ctx, item.Addr().Interface().(client.Object)); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
 func (cli *InfraClient) Delete(ctx context.Context, object client.Object) error {
 	if err := cli.Client.Delete(ctx, object); err != nil {
 		if kerrors.IsNotFound(err) {
diff --git a/internal/infrastructure/kubernetes/infra_resource.go b/internal/infrastructure/kubernetes/infra_resource.go
index 1bec17c090..6c2cacc2b4 100644
--- a/internal/infrastructure/kubernetes/infra_resource.go
+++ b/internal/infrastructure/kubernetes/infra_resource.go
@@ -119,6 +119,17 @@ func (i *Infra) createOrUpdateDeployment(ctx context.Context, r ResourceRender)
 	}
 
 	defer func() {
+		deleteErr := i.Client.DeleteAllExcept(ctx, &appsv1.DeploymentList{}, client.ObjectKey{
+			Namespace: deployment.Namespace,
+			Name:      deployment.Name,
+		}, &client.ListOptions{
+			Namespace:     deployment.Namespace,
+			LabelSelector: r.LabelSelector(),
+		})
+		if deleteErr != nil {
+			i.logger.Error(deleteErr, "failed to delete all except deployment", "name", r.Name())
+		}
+
 		if err == nil {
 			resourceApplyDurationSeconds.With(labels...).Record(time.Since(startTime).Seconds())
 			resourceApplyTotal.WithSuccess(labels...).Increment()
@@ -192,7 +203,7 @@ func (i *Infra) createOrUpdateDaemonSet(ctx context.Context, r ResourceRender) (
 		return err
 	}
 
-	// delete the daemonset and return early
+	// delete the DaemonSet and return early
 	// this handles the case where a deployment has been
 	// configured.
 	if daemonSet == nil {
@@ -200,6 +211,17 @@ func (i *Infra) createOrUpdateDaemonSet(ctx context.Context, r ResourceRender) (
 	}
 
 	defer func() {
+		deleteErr := i.Client.DeleteAllExcept(ctx, &appsv1.DaemonSetList{}, client.ObjectKey{
+			Namespace: daemonSet.Namespace,
+			Name:      daemonSet.Name,
+		}, &client.ListOptions{
+			Namespace:     daemonSet.Namespace,
+			LabelSelector: r.LabelSelector(),
+		})
+		if deleteErr != nil {
+			i.logger.Error(deleteErr, "failed to delete all except deployment", "name", r.Name())
+		}
+
 		if err == nil {
 			resourceApplyDurationSeconds.With(labels...).Record(time.Since(startTime).Seconds())
 			resourceApplyTotal.WithSuccess(labels...).Increment()
@@ -358,6 +380,17 @@ func (i *Infra) createOrUpdateService(ctx context.Context, r ResourceRender) (er
 	}
 
 	defer func() {
+		deleteErr := i.Client.DeleteAllExcept(ctx, &corev1.ServiceList{}, client.ObjectKey{
+			Namespace: svc.Namespace,
+			Name:      svc.Name,
+		}, &client.ListOptions{
+			Namespace:     svc.Namespace,
+			LabelSelector: r.LabelSelector(),
+		})
+		if deleteErr != nil {
+			i.logger.Error(deleteErr, "failed to delete all except deployment", "name", r.Name())
+		}
+
 		if err == nil {
 			resourceApplyDurationSeconds.With(labels...).Record(time.Since(startTime).Seconds())
 			resourceApplyTotal.WithSuccess(labels...).Increment()
diff --git a/release-notes/current.yaml b/release-notes/current.yaml
index 7f2b62ad45..1d76799569 100644
--- a/release-notes/current.yaml
+++ b/release-notes/current.yaml
@@ -38,6 +38,7 @@ bug fixes: |
   Fix not logging an error and returning it in the K8s Reconcile method when a GatewayClass is not accepted.
   Fix allowing empty text field for opentelemetry sink when using JSON format.
   Fix an issue that SamplingFraction was not working.
+  Fix kubernetes resources not being deleted when the customized name used.
 
 # Enhancements that improve performance.
 performance improvements: |
diff --git a/test/e2e/testdata/envoyproxy-custom-name.yaml b/test/e2e/testdata/envoyproxy-custom-name.yaml
new file mode 100644
index 0000000000..a1061025ef
--- /dev/null
+++ b/test/e2e/testdata/envoyproxy-custom-name.yaml
@@ -0,0 +1,120 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: deploy-custom-name
+  namespace: gateway-conformance-infra
+spec:
+  gatewayClassName: "{GATEWAY_CLASS_NAME}"
+  listeners:
+    - name: http
+      port: 80
+      protocol: HTTP
+      allowedRoutes:
+        namespaces:
+          from: All
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+  name: deploy-custom-name
+  namespace: gateway-conformance-infra
+spec:
+  ipFamily: IPv4
+  provider:
+    type: Kubernetes
+    kubernetes:
+      envoyDeployment:
+        name: deploy-custom-name
+      envoyService:
+        name: deploy-custom-name
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: deploy-route
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+    - name: deploy-custom-name
+  rules:
+    - backendRefs:
+        - name: infra-backend-v1
+          port: 8080
+      matches:
+        - path:
+            type: PathPrefix
+            value: /deploy
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: ds-custom-name
+  namespace: gateway-conformance-infra
+spec:
+  gatewayClassName: "{GATEWAY_CLASS_NAME}"
+  listeners:
+    - name: http
+      port: 80
+      protocol: HTTP
+      allowedRoutes:
+        namespaces:
+          from: All
+  infrastructure:
+    parametersRef:
+      group: gateway.envoyproxy.io
+      kind: EnvoyProxy
+      name: eg-daemonset
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+  name: eg-daemonset
+  namespace: gateway-conformance-infra
+spec:
+  ipFamily: IPv4
+  provider:
+    type: Kubernetes
+    kubernetes:
+      envoyDaemonSet:
+        patch:
+          type: StrategicMerge
+          value:
+            spec:
+              template:
+                spec:
+                  containers:
+                    - name: envoy
+                      readinessProbe:
+                        initialDelaySeconds: 5
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+  name: ds-custom-name
+  namespace: gateway-conformance-infra
+spec:
+  ipFamily: IPv4
+  provider:
+    type: Kubernetes
+    kubernetes:
+      envoyDaemonSet:
+        name: ds-custom-name
+      envoyService:
+        name: ds-custom-name
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: ds-route
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+    - name: ds-custom-name
+  rules:
+    - backendRefs:
+        - name: infra-backend-v1
+          port: 8080
+      matches:
+        - path:
+            type: PathPrefix
+            value: /daemonset
diff --git a/test/e2e/tests/envoyproxy.go b/test/e2e/tests/envoyproxy.go
new file mode 100644
index 0000000000..b8980bd096
--- /dev/null
+++ b/test/e2e/tests/envoyproxy.go
@@ -0,0 +1,315 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+
+package tests
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, EnvoyProxyCustomNameTest)
+}
+
+var EnvoyProxyCustomNameTest = suite.ConformanceTest{
+	ShortName:   "EnvoyProxyCustomName",
+	Description: "Test running Envoy with custom name",
+	Manifests:   []string{"testdata/envoyproxy-custom-name.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		t.Run("Deployment", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "deploy-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "deploy-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/deploy",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's deployment for the gateway
+			err := checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "deploy-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Rollback the Gateway to without custom name
+			gw = &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			// Make sure there's deployment for the gateway
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+		})
+
+		t.Run("DaemonSet", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "ds-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "ds-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/daemonset",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's DaemonSet for the gateway
+			err := checkEnvoyProxyDaemonSet(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "ds-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDaemonSet(t, suite, gwNN, "ds-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "ds-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Rollback the Gateway to without custom name
+			gw = &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "eg-daemonset",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			// Make sure there's DaemonSet for the gateway
+			err = checkEnvoyProxyDaemonSet(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+		})
+	},
+}
+
+func checkEnvoyProxyDeployment(t *testing.T, suite *suite.ConformanceTestSuite, gwNN types.NamespacedName, exceptName string) error {
+	// Make sure there's deployment for the gateway
+	return wait.PollUntilContextTimeout(context.TODO(), time.Second, suite.TimeoutConfig.CreateTimeout, true, func(ctx context.Context) (bool, error) {
+		deploys := &appsv1.DeploymentList{}
+		err := suite.Client.List(ctx, deploys, &client.ListOptions{
+			Namespace: "envoy-gateway-system",
+			LabelSelector: labels.SelectorFromSet(map[string]string{
+				"app.kubernetes.io/managed-by":                   "envoy-gateway",
+				"app.kubernetes.io/name":                         "envoy",
+				"gateway.envoyproxy.io/owning-gateway-name":      gwNN.Name,
+				"gateway.envoyproxy.io/owning-gateway-namespace": gwNN.Namespace,
+			}),
+		})
+		if err != nil {
+			return false, err
+		}
+		if len(deploys.Items) != 1 {
+			tlog.Logf(t, "Expected 1 Deployment for the Gateway, got %d", len(deploys.Items))
+			return false, nil
+		}
+
+		dp := deploys.Items[0]
+		if !strings.HasPrefix(dp.Name, exceptName) {
+			tlog.Logf(t, "Expected Deployment name has prefix '%s', got %s", exceptName, dp.Name)
+			return false, nil
+		}
+
+		if dp.Status.ReadyReplicas <= 0 {
+			tlog.Logf(t, "Expected Deployment %s ready", dp.Name)
+		}
+
+		tlog.Logf(t, "Check Envoy proxy deployment pass, name: %s", dp.Name)
+		return true, nil
+	})
+}
+
+func checkEnvoyProxyService(t *testing.T, suite *suite.ConformanceTestSuite, gwNN types.NamespacedName, exceptName string) error {
+	// Make sure there's deployment for the gateway
+	return wait.PollUntilContextTimeout(context.TODO(), time.Second, suite.TimeoutConfig.CreateTimeout, true, func(ctx context.Context) (bool, error) {
+		svcList := &corev1.ServiceList{}
+		err := suite.Client.List(ctx, svcList, &client.ListOptions{
+			Namespace: "envoy-gateway-system",
+			LabelSelector: labels.SelectorFromSet(map[string]string{
+				"app.kubernetes.io/managed-by":                   "envoy-gateway",
+				"app.kubernetes.io/name":                         "envoy",
+				"gateway.envoyproxy.io/owning-gateway-name":      gwNN.Name,
+				"gateway.envoyproxy.io/owning-gateway-namespace": gwNN.Namespace,
+			}),
+		})
+		if err != nil {
+			return false, err
+		}
+		if len(svcList.Items) != 1 {
+			tlog.Logf(t, "Expected 1 Service for the Gateway, got %d", len(svcList.Items))
+			return false, nil
+		}
+
+		svc := svcList.Items[0]
+		if !strings.HasPrefix(svc.Name, exceptName) {
+			tlog.Logf(t, "Expected Service name has prefix '%s', got %s", exceptName, svc.Name)
+			return false, nil
+		}
+
+		tlog.Logf(t, "Check envoy proxy service pass, name: %s", svc.Name)
+		return true, nil
+	})
+}
+
+func checkEnvoyProxyDaemonSet(t *testing.T, suite *suite.ConformanceTestSuite, gwNN types.NamespacedName, exceptName string) error {
+	// Make sure there's deployment for the gateway
+	return wait.PollUntilContextTimeout(context.TODO(), time.Second, suite.TimeoutConfig.CreateTimeout, true, func(ctx context.Context) (bool, error) {
+		dsList := &appsv1.DaemonSetList{}
+		err := suite.Client.List(ctx, dsList, &client.ListOptions{
+			Namespace: "envoy-gateway-system",
+			LabelSelector: labels.SelectorFromSet(map[string]string{
+				"app.kubernetes.io/managed-by":                   "envoy-gateway",
+				"app.kubernetes.io/name":                         "envoy",
+				"gateway.envoyproxy.io/owning-gateway-name":      gwNN.Name,
+				"gateway.envoyproxy.io/owning-gateway-namespace": gwNN.Namespace,
+			}),
+		})
+		if err != nil {
+			return false, err
+		}
+		if len(dsList.Items) != 1 {
+			tlog.Logf(t, "Expected 1 DaemonSet for the Gateway, got %d", len(dsList.Items))
+			return false, nil
+		}
+
+		ds := dsList.Items[0]
+		if !strings.HasPrefix(ds.Name, exceptName) {
+			tlog.Logf(t, "Expected DaemonSet name has prefix '%s', got %s", exceptName, ds.Name)
+			return false, nil
+		}
+
+		if ds.Status.NumberReady <= 0 {
+			tlog.Logf(t, "Expected DaemonSet %s ready", ds.Name)
+		}
+
+		tlog.Logf(t, "Check envoy proxy DaemonSet pass, name: %s", ds.Name)
+		return true, nil
+	})
+}


Reviews:
user: login: arkodg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T20:29:55Z
user: login: zirain
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T04:15:12Z
user: login: shawnh2
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-22T04:54:07Z
user: login: zirain
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T04:59:07Z
user: login: zirain
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T04:59:46Z
user: login: shawnh2
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-22T05:48:13Z
user: login: arkodg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T23:44:42Z
user: login: arkodg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T23:45:36Z
user: login: zirain
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-27T23:51:23Z
user: login: arkodg
body: LGTM thanks !
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T00:23:33Z
user: login: arkodg
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T01:58:40Z
user: login: cnvergence
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-28T15:09:19Z

Review comments:
diff_hunk: @@ -119,6 +119,16 @@ func (i *Infra) createOrUpdateDeployment(ctx context.Context, r ResourceRender)
 	}
 
 	defer func() {
+		// custom Deployment name is enabled, and the deployment name is different from the resource name.
path: internal/infrastructure/kubernetes/infra_resource.go
user: login: arkodg
body: this takes into account when default name changes to custom name, what about the case when custom name is removed and we switch to default name ?
my suggestion would be instead do a `Client.List` and delete all that are not current
created_at: 2025-03-21T20:29:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -119,6 +119,16 @@ func (i *Infra) createOrUpdateDeployment(ctx context.Context, r ResourceRender)
 	}
 
 	defer func() {
+		// custom Deployment name is enabled, and the deployment name is different from the resource name.
path: internal/infrastructure/kubernetes/infra_resource.go
user: login: zirain
body: good catch!
created_at: 2025-03-22T04:15:12Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,315 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+
+package tests
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, EnvoyProxyCustomNameTest)
+}
+
+var EnvoyProxyCustomNameTest = suite.ConformanceTest{
+	ShortName:   "EnvoyProxyCustomName",
+	Description: "Test running Envoy with custom name",
+	Manifests:   []string{"testdata/envoyproxy-custom-name.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		t.Run("Deployment", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "deploy-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "deploy-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/deploy",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's deployment for the gateway
+			err := checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "deploy-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Rollback the Gateway to without custom name
+			gw = &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			// Make sure there's deployment for the gateway
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+		})
+
+		t.Run("DaemonSet", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "ds-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "ds-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/daemonset",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's DaemonSet for the gateway
+			err := checkEnvoyProxyDaemonSet(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "ds-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDaemonSet(t, suite, gwNN, "ds-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "ds-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Rollback the Gateway to without custom name
+			gw = &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "eg-daemonset",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			// Make sure there's DaemonSet for the gateway
+			err = checkEnvoyProxyDaemonSet(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+		})
+	},
+}
+
+func checkEnvoyProxyDeployment(t *testing.T, suite *suite.ConformanceTestSuite, gwNN types.NamespacedName, exceptName string) error {
+	// Make sure there's deployment for the gateway
+	return wait.PollUntilContextTimeout(context.TODO(), time.Second, suite.TimeoutConfig.CreateTimeout, true, func(ctx context.Context) (bool, error) {
+		deploys := &appsv1.DeploymentList{}
+		err := suite.Client.List(ctx, deploys, &client.ListOptions{
+			Namespace: "envoy-gateway-system",
+			LabelSelector: labels.SelectorFromSet(map[string]string{
+				"app.kubernetes.io/managed-by":                   "envoy-gateway",
+				"app.kubernetes.io/name":                         "envoy",
+				"gateway.envoyproxy.io/owning-gateway-name":      gwNN.Name,
+				"gateway.envoyproxy.io/owning-gateway-namespace": gwNN.Namespace,
+			}),
+		})
+		if err != nil {
+			return false, err
+		}
+		if len(deploys.Items) != 1 {
+			tlog.Logf(t, "Expected 1 Deployment for the Gateway, got %d", len(deploys.Items))
+			return false, nil
+		}
+
+		dp := deploys.Items[0]
+		if !strings.HasPrefix(dp.Name, exceptName) {
+			tlog.Logf(t, "Expected Deployment name has prefix '%s', got %s", exceptName, dp.Name)
+			return false, nil
+		}
+
+		if dp.Status.ReadyReplicas <= 0 {
+			tlog.Logf(t, "Expected Deployment %s ready", dp.Name)
+		}
+
+		tlog.Logf(t, "Check Envoy proxy deployment pass, name: %s", dp.Name)
+		return true, nil
+	})
+}
+
+func checkEnvoyProxyService(t *testing.T, suite *suite.ConformanceTestSuite, gwNN types.NamespacedName, exceptName string) error {
path: test/e2e/tests/envoyproxy.go
user: login: shawnh2
body: can move these helper functions into utils.go?
created_at: 2025-03-22T04:52:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,315 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+
+package tests
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, EnvoyProxyCustomNameTest)
+}
+
+var EnvoyProxyCustomNameTest = suite.ConformanceTest{
+	ShortName:   "EnvoyProxyCustomName",
+	Description: "Test running Envoy with custom name",
+	Manifests:   []string{"testdata/envoyproxy-custom-name.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		t.Run("Deployment", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "deploy-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "deploy-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/deploy",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's deployment for the gateway
+			err := checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "deploy-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "deploy-custom-name")
path: test/e2e/tests/envoyproxy.go
user: login: shawnh2
body: should we check the old deployments and services exist?
created_at: 2025-03-22T04:53:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,315 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+
+package tests
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, EnvoyProxyCustomNameTest)
+}
+
+var EnvoyProxyCustomNameTest = suite.ConformanceTest{
+	ShortName:   "EnvoyProxyCustomName",
+	Description: "Test running Envoy with custom name",
+	Manifests:   []string{"testdata/envoyproxy-custom-name.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		t.Run("Deployment", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "deploy-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "deploy-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/deploy",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's deployment for the gateway
+			err := checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "deploy-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Rollback the Gateway to without custom name
+			gw = &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			// Make sure there's deployment for the gateway
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
path: test/e2e/tests/envoyproxy.go
user: login: shawnh2
body: ditto
created_at: 2025-03-22T04:53:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,315 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+
+package tests
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, EnvoyProxyCustomNameTest)
+}
+
+var EnvoyProxyCustomNameTest = suite.ConformanceTest{
+	ShortName:   "EnvoyProxyCustomName",
+	Description: "Test running Envoy with custom name",
+	Manifests:   []string{"testdata/envoyproxy-custom-name.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		t.Run("Deployment", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "deploy-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "deploy-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/deploy",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's deployment for the gateway
+			err := checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "deploy-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Rollback the Gateway to without custom name
+			gw = &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			// Make sure there's deployment for the gateway
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+		})
+
+		t.Run("DaemonSet", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "ds-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "ds-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/daemonset",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's DaemonSet for the gateway
+			err := checkEnvoyProxyDaemonSet(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "ds-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDaemonSet(t, suite, gwNN, "ds-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "ds-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Rollback the Gateway to without custom name
+			gw = &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "eg-daemonset",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			// Make sure there's DaemonSet for the gateway
+			err = checkEnvoyProxyDaemonSet(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr = kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+		})
+	},
+}
+
+func checkEnvoyProxyDeployment(t *testing.T, suite *suite.ConformanceTestSuite, gwNN types.NamespacedName, exceptName string) error {
+	// Make sure there's deployment for the gateway
+	return wait.PollUntilContextTimeout(context.TODO(), time.Second, suite.TimeoutConfig.CreateTimeout, true, func(ctx context.Context) (bool, error) {
+		deploys := &appsv1.DeploymentList{}
+		err := suite.Client.List(ctx, deploys, &client.ListOptions{
+			Namespace: "envoy-gateway-system",
+			LabelSelector: labels.SelectorFromSet(map[string]string{
+				"app.kubernetes.io/managed-by":                   "envoy-gateway",
+				"app.kubernetes.io/name":                         "envoy",
+				"gateway.envoyproxy.io/owning-gateway-name":      gwNN.Name,
+				"gateway.envoyproxy.io/owning-gateway-namespace": gwNN.Namespace,
+			}),
+		})
+		if err != nil {
+			return false, err
+		}
+		if len(deploys.Items) != 1 {
+			tlog.Logf(t, "Expected 1 Deployment for the Gateway, got %d", len(deploys.Items))
+			return false, nil
+		}
+
+		dp := deploys.Items[0]
+		if !strings.HasPrefix(dp.Name, exceptName) {
+			tlog.Logf(t, "Expected Deployment name has prefix '%s', got %s", exceptName, dp.Name)
+			return false, nil
+		}
+
+		if dp.Status.ReadyReplicas <= 0 {
+			tlog.Logf(t, "Expected Deployment %s ready", dp.Name)
+		}
+
+		tlog.Logf(t, "Check Envoy proxy deployment pass, name: %s", dp.Name)
+		return true, nil
+	})
+}
+
+func checkEnvoyProxyService(t *testing.T, suite *suite.ConformanceTestSuite, gwNN types.NamespacedName, exceptName string) error {
path: test/e2e/tests/envoyproxy.go
user: login: zirain
body: maybe in the future, right now these functions ensure only 1 items exists.
created_at: 2025-03-22T04:59:07Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,315 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+
+package tests
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, EnvoyProxyCustomNameTest)
+}
+
+var EnvoyProxyCustomNameTest = suite.ConformanceTest{
+	ShortName:   "EnvoyProxyCustomName",
+	Description: "Test running Envoy with custom name",
+	Manifests:   []string{"testdata/envoyproxy-custom-name.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		t.Run("Deployment", func(t *testing.T) {
+			ns := "gateway-conformance-infra"
+			routeNN := types.NamespacedName{Name: "deploy-route", Namespace: ns}
+			gwNN := types.NamespacedName{Name: "deploy-custom-name", Namespace: ns}
+			OkResp := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/deploy",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			// Make sure there's deployment for the gateway
+			err := checkEnvoyProxyDeployment(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy deployment: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, fmt.Sprintf("envoy-%s-%s", gwNN.Namespace, gwNN.Name))
+			if err != nil {
+				t.Fatalf("Failed to check EnvoyProxy service: %v", err)
+			}
+			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+			// Send a request to a valid path and expect a successful response
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp)
+
+			// Update the Gateway to use a custom name
+			gw := &gwapiv1.Gateway{}
+			err = suite.Client.Get(context.Background(), gwNN, gw)
+			if err != nil {
+				t.Fatalf("Failed to get Gateway: %v", err)
+			}
+			gw.Spec.Infrastructure = &gwapiv1.GatewayInfrastructure{
+				ParametersRef: &gwapiv1.LocalParametersReference{
+					Name:  "deploy-custom-name",
+					Kind:  "EnvoyProxy",
+					Group: "gateway.envoyproxy.io",
+				},
+			}
+			err = suite.Client.Update(context.Background(), gw)
+			if err != nil {
+				t.Fatalf("Failed to update Gateway: %v", err)
+			}
+
+			err = checkEnvoyProxyDeployment(t, suite, gwNN, "deploy-custom-name")
+			if err != nil {
+				t.Fatalf("Failed to delete Gateway: %v", err)
+			}
+			err = checkEnvoyProxyService(t, suite, gwNN, "deploy-custom-name")
path: test/e2e/tests/envoyproxy.go
user: login: zirain
body: we ensure there's only 1 item, see L229.
created_at: 2025-03-22T04:59:46Z
author_association: MEMBER
diff_hunk: @@ -67,6 +70,7 @@ func NewInfra(cli client.Client, cfg *config.Server) *Infra {
 		DNSDomain:    cfg.DNSDomain,
 		EnvoyGateway: cfg.EnvoyGateway,
 		Client:       New(cli),
+		logger:       cfg.Logger.WithName("infra-kubernetes"),
path: internal/infrastructure/kubernetes/infra.go
user: login: arkodg
body: won't be have `infrastructure` twice https://github.com/envoyproxy/gateway/blob/55fc01fecf2819af479aa1a3e5f4af37b737a947/api/v1alpha1/envoygateway_types.go#L148 ? should this be `kubernetes` instead ?
created_at: 2025-03-27T23:44:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -33,6 +34,41 @@ func (cli *InfraClient) ServerSideApply(ctx context.Context, obj client.Object)
 	return nil
 }
 
+// DeleteAllExcept delete all resources filter by ListOption except the one specified by key.
+func (cli *InfraClient) DeleteAllExcept(ctx context.Context, objList client.ObjectList, key client.ObjectKey, listOpts ...client.ListOption) error {
path: internal/infrastructure/kubernetes/infra_client.go
user: login: arkodg
body: nice !
created_at: 2025-03-27T23:45:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -67,6 +70,7 @@ func NewInfra(cli client.Client, cfg *config.Server) *Infra {
 		DNSDomain:    cfg.DNSDomain,
 		EnvoyGateway: cfg.EnvoyGateway,
 		Client:       New(cli),
+		logger:       cfg.Logger.WithName("infra-kubernetes"),
path: internal/infrastructure/kubernetes/infra.go
user: login: zirain
body: fixed
created_at: 2025-03-27T23:51:23Z
author_association: MEMBER

PR comments:
user: login: codecov[bot]
created_at: 2025-03-21T06:10:14Z
body: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/5569?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) Report
Attention: Patch coverage is `55.35714%` with `25 lines` in your changes missing coverage. Please review.
> Project coverage is 65.25%. Comparing base [(`555ec03`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/555ec030db455fbf7686f11a82e34c34849f62f5?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`bd72555`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/bd72555f67f6165b0548b2dfd6d2880377d5a5b8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).
> Report is 2 commits behind head on main.

| [Files with missing lines](https://app.codecov.io/gh/envoyproxy/gateway/pull/5569?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) | Patch % | Lines |
|---|---|---|
| [internal/infrastructure/kubernetes/infra\_client.go](https://app.codecov.io/gh/envoyproxy/gateway/pull/5569?src=pr&el=tree&filepath=internal%2Finfrastructure%2Fkubernetes%2Finfra_client.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy#diff-aW50ZXJuYWwvaW5mcmFzdHJ1Y3R1cmUva3ViZXJuZXRlcy9pbmZyYV9jbGllbnQuZ28=) | 36.00% | [15 Missing and 1 partial :warning: ](https://app.codecov.io/gh/envoyproxy/gateway/pull/5569?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) |
| [...ternal/infrastructure/kubernetes/infra\_resource.go](https://app.codecov.io/gh/envoyproxy/gateway/pull/5569?src=pr&el=tree&filepath=internal%2Finfrastructure%2Fkubernetes%2Finfra_resource.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy#diff-aW50ZXJuYWwvaW5mcmFzdHJ1Y3R1cmUva3ViZXJuZXRlcy9pbmZyYV9yZXNvdXJjZS5nbw==) | 70.00% | [6 Missing and 3 partials :warning: ](https://app.codecov.io/gh/envoyproxy/gateway/pull/5569?src=pr&el=tree&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    #5569      +/-   ##
==========================================
- Coverage   65.26%   65.25%   -0.02%     
==========================================
  Files         213      213              
  Lines       34073    34129      +56     
==========================================
+ Hits        22237    22270      +33     
- Misses      10501    10521      +20     
- Partials     1335     1338       +3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/5569?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).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE
user: login: zirain
created_at: 2025-03-22T04:17:37Z
body: @arkodg should we highlight that EG does not guarantee with zero downtime when using customized name?
author_association: MEMBER