github.com/cilium/cilium@v1.16.2/operator/pkg/model/translation/gateway-api/translator_fixture_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package gateway_api
     5  
     6  import (
     7  	"fmt"
     8  	"syscall"
     9  
    10  	envoy_config_cluster_v3 "github.com/cilium/proxy/go/envoy/config/cluster/v3"
    11  	envoy_config_core_v3 "github.com/cilium/proxy/go/envoy/config/core/v3"
    12  	envoy_config_listener "github.com/cilium/proxy/go/envoy/config/listener/v3"
    13  	envoy_config_route_v3 "github.com/cilium/proxy/go/envoy/config/route/v3"
    14  	grpc_stats_v3 "github.com/cilium/proxy/go/envoy/extensions/filters/http/grpc_stats/v3"
    15  	grpc_web_v3 "github.com/cilium/proxy/go/envoy/extensions/filters/http/grpc_web/v3"
    16  	envoy_extensions_filters_http_router_v3 "github.com/cilium/proxy/go/envoy/extensions/filters/http/router/v3"
    17  	envoy_extensions_listener_tls_inspector_v3 "github.com/cilium/proxy/go/envoy/extensions/filters/listener/tls_inspector/v3"
    18  	http_connection_manager_v3 "github.com/cilium/proxy/go/envoy/extensions/filters/network/http_connection_manager/v3"
    19  	envoy_extensions_filters_network_tcp_v3 "github.com/cilium/proxy/go/envoy/extensions/filters/network/tcp_proxy/v3"
    20  	envoy_extensions_transport_sockets_tls_v3 "github.com/cilium/proxy/go/envoy/extensions/transport_sockets/tls/v3"
    21  	envoy_upstreams_http_v3 "github.com/cilium/proxy/go/envoy/extensions/upstreams/http/v3"
    22  	envoy_type_matcher_v3 "github.com/cilium/proxy/go/envoy/type/matcher/v3"
    23  	envoy_type_v3 "github.com/cilium/proxy/go/envoy/type/v3"
    24  	"google.golang.org/protobuf/proto"
    25  	"google.golang.org/protobuf/types/known/anypb"
    26  	"google.golang.org/protobuf/types/known/durationpb"
    27  	"google.golang.org/protobuf/types/known/wrapperspb"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/utils/ptr"
    30  
    31  	"github.com/cilium/cilium/operator/pkg/model"
    32  	"github.com/cilium/cilium/operator/pkg/model/translation"
    33  	ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"
    34  	slim_metav1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/apis/meta/v1"
    35  )
    36  
    37  var (
    38  	backendV1XDSResource = toAny(toEnvoyCluster("gateway-conformance-infra", "infra-backend-v1", "8080"))
    39  	routeActionBackendV1 = toRouteAction("gateway-conformance-infra", "infra-backend-v1", "8080")
    40  )
    41  
    42  var (
    43  	backendV2XDSResource = toAny(toEnvoyCluster("gateway-conformance-infra", "infra-backend-v2", "8080"))
    44  	routeActionBackendV2 = toRouteAction("gateway-conformance-infra", "infra-backend-v2", "8080")
    45  )
    46  
    47  var (
    48  	backendV3XDSResource = toAny(toEnvoyCluster("gateway-conformance-infra", "infra-backend-v3", "8080"))
    49  	routeActionBackendV3 = toRouteAction("gateway-conformance-infra", "infra-backend-v3", "8080")
    50  )
    51  
    52  var backendProtocolH2CAppProtocol = translation.AppProtocolH2C
    53  
    54  var httpInsecureListenerXDSResource = toAny(&envoy_config_listener.Listener{
    55  	Name: "listener",
    56  	FilterChains: []*envoy_config_listener.FilterChain{
    57  		{
    58  			FilterChainMatch: &envoy_config_listener.FilterChainMatch{TransportProtocol: "raw_buffer"},
    59  			Filters: []*envoy_config_listener.Filter{
    60  				toListenerFilter("listener-insecure"),
    61  			},
    62  		},
    63  	},
    64  	ListenerFilters: []*envoy_config_listener.ListenerFilter{
    65  		{
    66  			Name: "envoy.filters.listener.tls_inspector",
    67  			ConfigType: &envoy_config_listener.ListenerFilter_TypedConfig{
    68  				TypedConfig: toAny(&envoy_extensions_listener_tls_inspector_v3.TlsInspector{}),
    69  			},
    70  		},
    71  	},
    72  	SocketOptions: toSocketOptions(),
    73  })
    74  
    75  var httpSecureListenerXDSResource = toAny(&envoy_config_listener.Listener{
    76  	Name: "listener",
    77  	FilterChains: []*envoy_config_listener.FilterChain{
    78  		{
    79  			FilterChainMatch: &envoy_config_listener.FilterChainMatch{TransportProtocol: "raw_buffer"},
    80  			Filters: []*envoy_config_listener.Filter{
    81  				toListenerFilter("listener-insecure"),
    82  			},
    83  		},
    84  		{
    85  			FilterChainMatch: &envoy_config_listener.FilterChainMatch{TransportProtocol: "tls", ServerNames: []string{"example.com"}},
    86  			Filters: []*envoy_config_listener.Filter{
    87  				toListenerFilter("listener-secure"),
    88  			},
    89  			TransportSocket: &envoy_config_core_v3.TransportSocket{
    90  				Name: "envoy.transport_sockets.tls",
    91  				ConfigType: &envoy_config_core_v3.TransportSocket_TypedConfig{
    92  					TypedConfig: toAny(&envoy_extensions_transport_sockets_tls_v3.DownstreamTlsContext{
    93  						CommonTlsContext: &envoy_extensions_transport_sockets_tls_v3.CommonTlsContext{
    94  							TlsCertificateSdsSecretConfigs: []*envoy_extensions_transport_sockets_tls_v3.SdsSecretConfig{
    95  								{
    96  									Name: "cilium-secrets/gateway-conformance-infra-tls-secure",
    97  								},
    98  							},
    99  						},
   100  					}),
   101  				},
   102  			},
   103  		},
   104  	},
   105  	ListenerFilters: []*envoy_config_listener.ListenerFilter{
   106  		{
   107  			Name: "envoy.filters.listener.tls_inspector",
   108  			ConfigType: &envoy_config_listener.ListenerFilter_TypedConfig{
   109  				TypedConfig: toAny(&envoy_extensions_listener_tls_inspector_v3.TlsInspector{}),
   110  			},
   111  		},
   112  	},
   113  	SocketOptions: toSocketOptions(),
   114  })
   115  
   116  func buildHTTPInsecureListenerXDSResourceWithXFF(routeName string, xffNumTrustedHops uint32) *anypb.Any {
   117  	return toAny(&envoy_config_listener.Listener{
   118  		Name: "listener",
   119  		FilterChains: []*envoy_config_listener.FilterChain{
   120  			{
   121  				FilterChainMatch: &envoy_config_listener.FilterChainMatch{TransportProtocol: "raw_buffer"},
   122  				Filters: []*envoy_config_listener.Filter{
   123  					{
   124  						Name: "envoy.filters.network.http_connection_manager",
   125  						ConfigType: &envoy_config_listener.Filter_TypedConfig{
   126  							TypedConfig: toAny(&http_connection_manager_v3.HttpConnectionManager{
   127  								StatPrefix: routeName,
   128  								RouteSpecifier: &http_connection_manager_v3.HttpConnectionManager_Rds{
   129  									Rds: &http_connection_manager_v3.Rds{RouteConfigName: routeName},
   130  								},
   131  								UpgradeConfigs: []*http_connection_manager_v3.HttpConnectionManager_UpgradeConfig{
   132  									{UpgradeType: "websocket"},
   133  								},
   134  								UseRemoteAddress:  &wrapperspb.BoolValue{Value: true},
   135  								SkipXffAppend:     false,
   136  								XffNumTrustedHops: xffNumTrustedHops,
   137  								HttpFilters: []*http_connection_manager_v3.HttpFilter{
   138  									{
   139  										Name: "envoy.filters.http.grpc_web",
   140  										ConfigType: &http_connection_manager_v3.HttpFilter_TypedConfig{
   141  											TypedConfig: toAny(&grpc_web_v3.GrpcWeb{}),
   142  										},
   143  									},
   144  									{
   145  										Name: "envoy.filters.http.grpc_stats",
   146  										ConfigType: &http_connection_manager_v3.HttpFilter_TypedConfig{
   147  											TypedConfig: toAny(&grpc_stats_v3.FilterConfig{
   148  												EmitFilterState:     true,
   149  												EnableUpstreamStats: true,
   150  											}),
   151  										},
   152  									},
   153  									{
   154  										Name: "envoy.filters.http.router",
   155  										ConfigType: &http_connection_manager_v3.HttpFilter_TypedConfig{
   156  											TypedConfig: toAny(&envoy_extensions_filters_http_router_v3.Router{}),
   157  										},
   158  									},
   159  								},
   160  								CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{
   161  									MaxStreamDuration: &durationpb.Duration{
   162  										Seconds: 0,
   163  									},
   164  								},
   165  							}),
   166  						},
   167  					},
   168  				},
   169  			},
   170  		},
   171  		ListenerFilters: []*envoy_config_listener.ListenerFilter{
   172  			{
   173  				Name: "envoy.filters.listener.tls_inspector",
   174  				ConfigType: &envoy_config_listener.ListenerFilter_TypedConfig{
   175  					TypedConfig: toAny(&envoy_extensions_listener_tls_inspector_v3.TlsInspector{}),
   176  				},
   177  			},
   178  		},
   179  		SocketOptions: toSocketOptions(),
   180  	})
   181  }
   182  
   183  func httpInsecureHostPortListenerXDSResource(address string, port uint32) *anypb.Any {
   184  	return toAny(&envoy_config_listener.Listener{
   185  		Name: "listener",
   186  		Address: &envoy_config_core_v3.Address{
   187  			Address: &envoy_config_core_v3.Address_SocketAddress{
   188  				SocketAddress: &envoy_config_core_v3.SocketAddress{
   189  					Protocol: envoy_config_core_v3.SocketAddress_TCP,
   190  					Address:  address,
   191  					PortSpecifier: &envoy_config_core_v3.SocketAddress_PortValue{
   192  						PortValue: port,
   193  					},
   194  				},
   195  			},
   196  		},
   197  		FilterChains: []*envoy_config_listener.FilterChain{
   198  			{
   199  				FilterChainMatch: &envoy_config_listener.FilterChainMatch{TransportProtocol: "raw_buffer"},
   200  				Filters: []*envoy_config_listener.Filter{
   201  					toListenerFilter("listener-insecure"),
   202  				},
   203  			},
   204  		},
   205  		ListenerFilters: []*envoy_config_listener.ListenerFilter{
   206  			{
   207  				Name: "envoy.filters.listener.tls_inspector",
   208  				ConfigType: &envoy_config_listener.ListenerFilter_TypedConfig{
   209  					TypedConfig: toAny(&envoy_extensions_listener_tls_inspector_v3.TlsInspector{}),
   210  				},
   211  			},
   212  		},
   213  		SocketOptions: toSocketOptions(),
   214  	})
   215  }
   216  
   217  // basicHTTPListeners is the internal model representation of the simple HTTP listeners
   218  func basicHTTPListeners(port uint32) []model.HTTPListener {
   219  	return []model.HTTPListener{
   220  		{
   221  			Name: "prod-web-gw",
   222  			Sources: []model.FullyQualifiedResource{
   223  				{
   224  					Name:      "my-gateway",
   225  					Namespace: "default",
   226  					Group:     "gateway.networking.k8s.io",
   227  					Version:   "v1",
   228  					Kind:      "Gateway",
   229  				},
   230  			},
   231  			Address:  "",
   232  			Port:     port,
   233  			Hostname: "*",
   234  			Routes: []model.HTTPRoute{
   235  				{
   236  					PathMatch: model.StringMatch{
   237  						Prefix: "/bar",
   238  					},
   239  					Backends: []model.Backend{
   240  						{
   241  							Name:      "my-service",
   242  							Namespace: "default",
   243  							Port: &model.BackendPort{
   244  								Port: 8080,
   245  							},
   246  						},
   247  					},
   248  				},
   249  			},
   250  		},
   251  	}
   252  }
   253  
   254  // basicHTTPListenersCiliumEnvoyConfig is the generated CiliumEnvoyConfig basic http listener model.
   255  var basicHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
   256  	ObjectMeta: metav1.ObjectMeta{
   257  		Name:      "cilium-gateway-my-gateway",
   258  		Namespace: "default",
   259  		Labels: map[string]string{
   260  			"cilium.io/use-original-source-address":  "false",
   261  			"gateway.networking.k8s.io/gateway-name": "my-gateway",
   262  		},
   263  		OwnerReferences: []metav1.OwnerReference{
   264  			{
   265  				APIVersion: "gateway.networking.k8s.io/v1",
   266  				Kind:       "Gateway",
   267  				Name:       "my-gateway",
   268  				Controller: model.AddressOf(true),
   269  			},
   270  		},
   271  	},
   272  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
   273  		Services: []*ciliumv2.ServiceListener{
   274  			{
   275  				Name:      "cilium-gateway-my-gateway",
   276  				Namespace: "default",
   277  				Ports: []uint16{
   278  					80,
   279  				},
   280  			},
   281  		},
   282  		BackendServices: []*ciliumv2.Service{
   283  			{
   284  				Name:      "my-service",
   285  				Namespace: "default",
   286  				Ports:     []string{"8080"},
   287  			},
   288  		},
   289  		Resources: []ciliumv2.XDSResource{
   290  			{Any: httpInsecureListenerXDSResource},
   291  			{
   292  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
   293  					Name: "listener-insecure",
   294  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
   295  						{
   296  							Name:    "*",
   297  							Domains: []string{"*"},
   298  							Routes: []*envoy_config_route_v3.Route{
   299  								{
   300  									Match: &envoy_config_route_v3.RouteMatch{
   301  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
   302  											PathSeparatedPrefix: "/bar",
   303  										},
   304  									},
   305  									Action: toRouteAction("default", "my-service", "8080"),
   306  								},
   307  							},
   308  						},
   309  					},
   310  				}),
   311  			},
   312  			{Any: toAny(toEnvoyCluster("default", "my-service", "8080"))},
   313  		},
   314  	},
   315  }
   316  
   317  // basicHTTPListenersCiliumEnvoyConfigWithXff is the generated CiliumEnvoyConfig basic http listener model with XffNumTrustedHops.
   318  var basicHTTPListenersCiliumEnvoyConfigWithXff = &ciliumv2.CiliumEnvoyConfig{
   319  	ObjectMeta: metav1.ObjectMeta{
   320  		Name:      "cilium-gateway-my-gateway",
   321  		Namespace: "default",
   322  		Labels: map[string]string{
   323  			"cilium.io/use-original-source-address":  "false",
   324  			"gateway.networking.k8s.io/gateway-name": "my-gateway",
   325  		},
   326  		OwnerReferences: []metav1.OwnerReference{
   327  			{
   328  				APIVersion: "gateway.networking.k8s.io/v1",
   329  				Kind:       "Gateway",
   330  				Name:       "my-gateway",
   331  				Controller: model.AddressOf(true),
   332  			},
   333  		},
   334  	},
   335  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
   336  		Services: []*ciliumv2.ServiceListener{
   337  			{
   338  				Name:      "cilium-gateway-my-gateway",
   339  				Namespace: "default",
   340  				Ports: []uint16{
   341  					80,
   342  				},
   343  			},
   344  		},
   345  		BackendServices: []*ciliumv2.Service{
   346  			{
   347  				Name:      "my-service",
   348  				Namespace: "default",
   349  				Ports:     []string{"8080"},
   350  			},
   351  		},
   352  		Resources: []ciliumv2.XDSResource{
   353  			{Any: buildHTTPInsecureListenerXDSResourceWithXFF("listener-insecure", 2)},
   354  			{
   355  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
   356  					Name: "listener-insecure",
   357  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
   358  						{
   359  							Name:    "*",
   360  							Domains: []string{"*"},
   361  							Routes: []*envoy_config_route_v3.Route{
   362  								{
   363  									Match: &envoy_config_route_v3.RouteMatch{
   364  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
   365  											PathSeparatedPrefix: "/bar",
   366  										},
   367  									},
   368  									Action: toRouteAction("default", "my-service", "8080"),
   369  								},
   370  							},
   371  						},
   372  					},
   373  				}),
   374  			},
   375  			{Any: toAny(toEnvoyCluster("default", "my-service", "8080"))},
   376  		},
   377  	},
   378  }
   379  
   380  // basicHostPortHTTPListenersCiliumEnvoyConfig is the generated CiliumEnvoyConfig basic http listener model.
   381  func basicHostPortHTTPListenersCiliumEnvoyConfig(address string, port uint32, nodeLabelSelector *slim_metav1.LabelSelector) *ciliumv2.CiliumEnvoyConfig {
   382  	return &ciliumv2.CiliumEnvoyConfig{
   383  		ObjectMeta: metav1.ObjectMeta{
   384  			Name:      "cilium-gateway-my-gateway",
   385  			Namespace: "default",
   386  			Labels: map[string]string{
   387  				"cilium.io/use-original-source-address":  "false",
   388  				"gateway.networking.k8s.io/gateway-name": "my-gateway",
   389  			},
   390  			OwnerReferences: []metav1.OwnerReference{
   391  				{
   392  					APIVersion: "gateway.networking.k8s.io/v1",
   393  					Kind:       "Gateway",
   394  					Name:       "my-gateway",
   395  					Controller: model.AddressOf(true),
   396  				},
   397  			},
   398  		},
   399  		Spec: ciliumv2.CiliumEnvoyConfigSpec{
   400  			NodeSelector: nodeLabelSelector,
   401  			Services: []*ciliumv2.ServiceListener{
   402  				{
   403  					Name:      "cilium-gateway-my-gateway",
   404  					Namespace: "default",
   405  					Ports: []uint16{
   406  						uint16(port),
   407  					},
   408  				},
   409  			},
   410  			BackendServices: []*ciliumv2.Service{
   411  				{
   412  					Name:      "my-service",
   413  					Namespace: "default",
   414  					Ports:     []string{"8080"},
   415  				},
   416  			},
   417  			Resources: []ciliumv2.XDSResource{
   418  				{Any: httpInsecureHostPortListenerXDSResource(address, port)},
   419  				{
   420  					Any: toAny(&envoy_config_route_v3.RouteConfiguration{
   421  						Name: "listener-insecure",
   422  						VirtualHosts: []*envoy_config_route_v3.VirtualHost{
   423  							{
   424  								Name:    "*",
   425  								Domains: []string{"*"},
   426  								Routes: []*envoy_config_route_v3.Route{
   427  									{
   428  										Match: &envoy_config_route_v3.RouteMatch{
   429  											PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
   430  												PathSeparatedPrefix: "/bar",
   431  											},
   432  										},
   433  										Action: toRouteAction("default", "my-service", "8080"),
   434  									},
   435  								},
   436  							},
   437  						},
   438  					}),
   439  				},
   440  				{Any: toAny(toEnvoyCluster("default", "my-service", "8080"))},
   441  			},
   442  		},
   443  	}
   444  }
   445  
   446  // basicTLSListeners is the internal model representation of the simple TLS listeners
   447  var basicTLSListeners = []model.TLSPassthroughListener{
   448  	{
   449  		Name: "prod-web-gw",
   450  		Sources: []model.FullyQualifiedResource{
   451  			{
   452  				Name:      "my-gateway",
   453  				Namespace: "default",
   454  				Group:     "gateway.networking.k8s.io",
   455  				Version:   "v1",
   456  				Kind:      "Gateway",
   457  			},
   458  		},
   459  		Address:  "",
   460  		Port:     443,
   461  		Hostname: "*",
   462  		Routes: []model.TLSPassthroughRoute{
   463  			{
   464  				Hostnames: []string{"foo.com"},
   465  				Backends: []model.Backend{
   466  					{
   467  						Name:      "my-service",
   468  						Namespace: "default",
   469  						Port: &model.BackendPort{
   470  							Port: 8080,
   471  						},
   472  					},
   473  				},
   474  			},
   475  		},
   476  	},
   477  }
   478  
   479  var basicTLSListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
   480  	ObjectMeta: metav1.ObjectMeta{
   481  		Name:      "cilium-gateway-my-gateway",
   482  		Namespace: "default",
   483  		Labels: map[string]string{
   484  			"cilium.io/use-original-source-address":  "false",
   485  			"gateway.networking.k8s.io/gateway-name": "my-gateway",
   486  		},
   487  		OwnerReferences: []metav1.OwnerReference{
   488  			{
   489  				APIVersion: "gateway.networking.k8s.io/v1",
   490  				Kind:       "Gateway",
   491  				Name:       "my-gateway",
   492  				Controller: model.AddressOf(true),
   493  			},
   494  		},
   495  	},
   496  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
   497  		Services: []*ciliumv2.ServiceListener{
   498  			{
   499  				Name:      "cilium-gateway-my-gateway",
   500  				Namespace: "default",
   501  				Ports: []uint16{
   502  					443,
   503  				},
   504  			},
   505  		},
   506  		BackendServices: []*ciliumv2.Service{
   507  			{
   508  				Name:      "my-service",
   509  				Namespace: "default",
   510  				Ports:     []string{"8080"},
   511  			},
   512  		},
   513  		Resources: []ciliumv2.XDSResource{
   514  			{
   515  				Any: toAny(&envoy_config_listener.Listener{
   516  					Name: "listener",
   517  					FilterChains: []*envoy_config_listener.FilterChain{
   518  						{
   519  							FilterChainMatch: &envoy_config_listener.FilterChainMatch{
   520  								ServerNames:       []string{"foo.com"},
   521  								TransportProtocol: "tls",
   522  							},
   523  							Filters: []*envoy_config_listener.Filter{
   524  								{
   525  									Name: "envoy.filters.network.tcp_proxy",
   526  									ConfigType: &envoy_config_listener.Filter_TypedConfig{
   527  										TypedConfig: toAny(&envoy_extensions_filters_network_tcp_v3.TcpProxy{
   528  											StatPrefix: "default:my-service:8080",
   529  											ClusterSpecifier: &envoy_extensions_filters_network_tcp_v3.TcpProxy_Cluster{
   530  												Cluster: "default:my-service:8080",
   531  											},
   532  										}),
   533  									},
   534  								},
   535  							},
   536  						},
   537  					},
   538  					ListenerFilters: []*envoy_config_listener.ListenerFilter{
   539  						{
   540  							Name: "envoy.filters.listener.tls_inspector",
   541  							ConfigType: &envoy_config_listener.ListenerFilter_TypedConfig{
   542  								TypedConfig: toAny(&envoy_extensions_listener_tls_inspector_v3.TlsInspector{}),
   543  							},
   544  						},
   545  					},
   546  					SocketOptions: toSocketOptions(),
   547  				}),
   548  			},
   549  			{
   550  				Any: toAny(&envoy_config_cluster_v3.Cluster{
   551  					Name: "default:my-service:8080",
   552  					EdsClusterConfig: &envoy_config_cluster_v3.Cluster_EdsClusterConfig{
   553  						ServiceName: "default/my-service:8080",
   554  					},
   555  					ClusterDiscoveryType: &envoy_config_cluster_v3.Cluster_Type{
   556  						Type: envoy_config_cluster_v3.Cluster_EDS,
   557  					},
   558  					ConnectTimeout: &durationpb.Duration{Seconds: int64(5)},
   559  					LbPolicy:       envoy_config_cluster_v3.Cluster_ROUND_ROBIN,
   560  					OutlierDetection: &envoy_config_cluster_v3.OutlierDetection{
   561  						SplitExternalLocalOriginErrors: true,
   562  					},
   563  				}),
   564  			},
   565  		},
   566  	},
   567  }
   568  
   569  // simpleSameNamespaceHTTPListeners is the internal model representation of Conformance/HTTPRouteSimpleSameNamespace
   570  var simpleSameNamespaceHTTPListeners = []model.HTTPListener{
   571  	{
   572  		Name: "http",
   573  		Sources: []model.FullyQualifiedResource{
   574  			{
   575  				Name:      "same-namespace",
   576  				Namespace: "gateway-conformance-infra",
   577  				Group:     "gateway.networking.k8s.io",
   578  				Version:   "v1",
   579  				Kind:      "Gateway",
   580  			},
   581  		},
   582  		Port:     80,
   583  		Hostname: "*",
   584  		Routes: []model.HTTPRoute{
   585  			{
   586  				Backends: []model.Backend{
   587  					{
   588  						Name:      "infra-backend-v1",
   589  						Namespace: "gateway-conformance-infra",
   590  						Port: &model.BackendPort{
   591  							Port: 8080,
   592  						},
   593  					},
   594  				},
   595  			},
   596  		},
   597  	},
   598  }
   599  
   600  var simpleSameNamespaceHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
   601  	ObjectMeta: metav1.ObjectMeta{
   602  		Name:      "cilium-gateway-same-namespace",
   603  		Namespace: "gateway-conformance-infra",
   604  		Labels: map[string]string{
   605  			"cilium.io/use-original-source-address":  "false",
   606  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
   607  		},
   608  		OwnerReferences: []metav1.OwnerReference{
   609  			{
   610  				APIVersion: "gateway.networking.k8s.io/v1",
   611  				Kind:       "Gateway",
   612  				Name:       "same-namespace",
   613  				Controller: model.AddressOf(true),
   614  			},
   615  		},
   616  	},
   617  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
   618  		Services: []*ciliumv2.ServiceListener{
   619  			{
   620  				Name:      "cilium-gateway-same-namespace",
   621  				Namespace: "gateway-conformance-infra",
   622  				Ports: []uint16{
   623  					80,
   624  				},
   625  			},
   626  		},
   627  		BackendServices: []*ciliumv2.Service{
   628  			{
   629  				Name:      "infra-backend-v1",
   630  				Namespace: "gateway-conformance-infra",
   631  				Ports:     []string{"8080"},
   632  			},
   633  		},
   634  		Resources: []ciliumv2.XDSResource{
   635  			{Any: httpInsecureListenerXDSResource},
   636  			{
   637  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
   638  					Name: "listener-insecure",
   639  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
   640  						{
   641  							Name:    "*",
   642  							Domains: []string{"*"},
   643  							Routes: []*envoy_config_route_v3.Route{
   644  								{
   645  									Match: &envoy_config_route_v3.RouteMatch{
   646  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
   647  											Prefix: "/",
   648  										},
   649  									},
   650  									Action: routeActionBackendV1,
   651  								},
   652  							},
   653  						},
   654  					},
   655  				}),
   656  			},
   657  			{Any: backendV1XDSResource},
   658  		},
   659  	},
   660  }
   661  
   662  // backendProtocolDisabledH2CHTTPListeners is the internal model representation of Conformance/HTTPRouteBackendProtocolH2C
   663  var backendProtocolDisabledH2CHTTPListeners = []model.HTTPListener{
   664  	{
   665  		Name: "http",
   666  		Sources: []model.FullyQualifiedResource{
   667  			{
   668  				Name:      "same-namespace",
   669  				Namespace: "gateway-conformance-infra",
   670  				Group:     "gateway.networking.k8s.io",
   671  				Version:   "v1",
   672  				Kind:      "Gateway",
   673  			},
   674  		},
   675  		Port:     80,
   676  		Hostname: "*",
   677  		Routes: []model.HTTPRoute{
   678  			{
   679  				Backends: []model.Backend{
   680  					{
   681  						Name:      "infra-backend-v1",
   682  						Namespace: "gateway-conformance-infra",
   683  						Port: &model.BackendPort{
   684  							Port: 8080,
   685  						},
   686  						AppProtocol: &backendProtocolH2CAppProtocol,
   687  					},
   688  				},
   689  			},
   690  		},
   691  	},
   692  }
   693  
   694  // backendProtocolEnabledH2CHTTPListeners is the internal model representation of Conformance/HTTPRouteBackendProtocolH2C
   695  var backendProtocolEnabledH2CHTTPListeners = []model.HTTPListener{
   696  	{
   697  		Name: "http",
   698  		Sources: []model.FullyQualifiedResource{
   699  			{
   700  				Name:      "same-namespace",
   701  				Namespace: "gateway-conformance-infra",
   702  				Group:     "gateway.networking.k8s.io",
   703  				Version:   "v1",
   704  				Kind:      "Gateway",
   705  			},
   706  		},
   707  		Port:     80,
   708  		Hostname: "*",
   709  		Routes: []model.HTTPRoute{
   710  			{
   711  				Backends: []model.Backend{
   712  					{
   713  						Name:      "backend-protocol-h2c",
   714  						Namespace: "gateway-conformance-infra",
   715  						Port: &model.BackendPort{
   716  							Port: 8080,
   717  						},
   718  						AppProtocol: &backendProtocolH2CAppProtocol,
   719  					},
   720  				},
   721  			},
   722  		},
   723  	},
   724  }
   725  
   726  var backendProtocolEnabledH2CHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
   727  	ObjectMeta: metav1.ObjectMeta{
   728  		Name:      "cilium-gateway-same-namespace",
   729  		Namespace: "gateway-conformance-infra",
   730  		Labels: map[string]string{
   731  			"cilium.io/use-original-source-address":  "false",
   732  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
   733  		},
   734  		OwnerReferences: []metav1.OwnerReference{
   735  			{
   736  				APIVersion: "gateway.networking.k8s.io/v1",
   737  				Kind:       "Gateway",
   738  				Name:       "same-namespace",
   739  				Controller: model.AddressOf(true),
   740  			},
   741  		},
   742  	},
   743  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
   744  		Services: []*ciliumv2.ServiceListener{
   745  			{
   746  				Name:      "cilium-gateway-same-namespace",
   747  				Namespace: "gateway-conformance-infra",
   748  				Ports: []uint16{
   749  					80,
   750  				},
   751  			},
   752  		},
   753  		BackendServices: []*ciliumv2.Service{
   754  			{
   755  				Name:      "backend-protocol-h2c",
   756  				Namespace: "gateway-conformance-infra",
   757  				Ports:     []string{"8080"},
   758  			},
   759  		},
   760  		Resources: []ciliumv2.XDSResource{
   761  			{Any: httpInsecureListenerXDSResource},
   762  			{
   763  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
   764  					Name: "listener-insecure",
   765  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
   766  						{
   767  							Name:    "*",
   768  							Domains: []string{"*"},
   769  							Routes: []*envoy_config_route_v3.Route{
   770  								{
   771  									Match: &envoy_config_route_v3.RouteMatch{
   772  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
   773  											Prefix: "/",
   774  										},
   775  									},
   776  									Action: toRouteAction("gateway-conformance-infra", "backend-protocol-h2c", "8080"),
   777  								},
   778  							},
   779  						},
   780  					},
   781  				}),
   782  			},
   783  			{Any: toAny(toEnvoyClusterHTTP2("gateway-conformance-infra", "backend-protocol-h2c", "8080"))},
   784  		},
   785  	},
   786  }
   787  
   788  // crossNamespaceHTTPListeners is the internal model representation of the Conformance/HTTPRouteCrossNamespace
   789  var crossNamespaceHTTPListeners = []model.HTTPListener{
   790  	{
   791  		Name: "http",
   792  		Sources: []model.FullyQualifiedResource{
   793  			{
   794  				Name:      "backend-namespaces",
   795  				Namespace: "gateway-conformance-infra",
   796  				Group:     "gateway.networking.k8s.io",
   797  				Version:   "v1",
   798  				Kind:      "Gateway",
   799  			},
   800  		},
   801  		Port:     80,
   802  		Hostname: "*",
   803  		Routes: []model.HTTPRoute{
   804  			{
   805  				Backends: []model.Backend{
   806  					{
   807  						Name:      "web-backend",
   808  						Namespace: "gateway-conformance-web-backend",
   809  						Port: &model.BackendPort{
   810  							Port: 8080,
   811  						},
   812  					},
   813  				},
   814  			},
   815  		},
   816  	},
   817  }
   818  
   819  var crossNamespaceHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
   820  	ObjectMeta: metav1.ObjectMeta{
   821  		Name:      "cilium-gateway-backend-namespaces",
   822  		Namespace: "gateway-conformance-infra",
   823  		Labels: map[string]string{
   824  			"cilium.io/use-original-source-address":  "false",
   825  			"gateway.networking.k8s.io/gateway-name": "backend-namespaces",
   826  		},
   827  		OwnerReferences: []metav1.OwnerReference{
   828  			{
   829  				APIVersion: "gateway.networking.k8s.io/v1",
   830  				Kind:       "Gateway",
   831  				Name:       "backend-namespaces",
   832  				Controller: model.AddressOf(true),
   833  			},
   834  		},
   835  	},
   836  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
   837  		Services: []*ciliumv2.ServiceListener{
   838  			{
   839  				Name:      "cilium-gateway-backend-namespaces",
   840  				Namespace: "gateway-conformance-infra",
   841  				Ports: []uint16{
   842  					80,
   843  				},
   844  			},
   845  		},
   846  		BackendServices: []*ciliumv2.Service{
   847  			{
   848  				Name:      "web-backend",
   849  				Namespace: "gateway-conformance-web-backend",
   850  				Ports:     []string{"8080"},
   851  			},
   852  		},
   853  		Resources: []ciliumv2.XDSResource{
   854  			{Any: httpInsecureListenerXDSResource},
   855  			{
   856  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
   857  					Name: "listener-insecure",
   858  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
   859  						{
   860  							Name:    "*",
   861  							Domains: []string{"*"},
   862  							Routes: []*envoy_config_route_v3.Route{
   863  								{
   864  									Match: &envoy_config_route_v3.RouteMatch{
   865  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
   866  											Prefix: "/",
   867  										},
   868  									},
   869  									Action: toRouteAction("gateway-conformance-web-backend", "web-backend", "8080"),
   870  								},
   871  							},
   872  						},
   873  					},
   874  				}),
   875  			},
   876  			{Any: toAny(toEnvoyCluster("gateway-conformance-web-backend", "web-backend", "8080"))},
   877  		},
   878  	},
   879  }
   880  
   881  // exactPathMatchingHTTPListeners is the internal model representation of Conformance/HTTPExactPathMatching
   882  var exactPathMatchingHTTPListeners = []model.HTTPListener{
   883  	{
   884  		Name: "http",
   885  		Sources: []model.FullyQualifiedResource{
   886  			{
   887  				Name:      "same-namespace",
   888  				Namespace: "gateway-conformance-infra",
   889  				Group:     "gateway.networking.k8s.io",
   890  				Version:   "v1",
   891  				Kind:      "Gateway",
   892  			},
   893  		},
   894  		Port:     80,
   895  		Hostname: "*",
   896  		Routes: []model.HTTPRoute{
   897  			{
   898  				PathMatch: model.StringMatch{Exact: "/one"},
   899  				Backends: []model.Backend{
   900  					{
   901  						Name:      "infra-backend-v1",
   902  						Namespace: "gateway-conformance-infra",
   903  						Port: &model.BackendPort{
   904  							Port: 8080,
   905  						},
   906  					},
   907  				},
   908  			},
   909  			{
   910  				PathMatch: model.StringMatch{Exact: "/two"},
   911  				Backends: []model.Backend{
   912  					{
   913  						Name:      "infra-backend-v2",
   914  						Namespace: "gateway-conformance-infra",
   915  						Port: &model.BackendPort{
   916  							Port: 8080,
   917  						},
   918  					},
   919  				},
   920  			},
   921  		},
   922  	},
   923  }
   924  
   925  var exactPathMatchingHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
   926  	ObjectMeta: metav1.ObjectMeta{
   927  		Name:      "cilium-gateway-same-namespace",
   928  		Namespace: "gateway-conformance-infra",
   929  		Labels: map[string]string{
   930  			"cilium.io/use-original-source-address":  "false",
   931  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
   932  		},
   933  		OwnerReferences: []metav1.OwnerReference{
   934  			{
   935  				APIVersion: "gateway.networking.k8s.io/v1",
   936  				Kind:       "Gateway",
   937  				Name:       "same-namespace",
   938  				Controller: model.AddressOf(true),
   939  			},
   940  		},
   941  	},
   942  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
   943  		Services: []*ciliumv2.ServiceListener{
   944  			{
   945  				Name:      "cilium-gateway-same-namespace",
   946  				Namespace: "gateway-conformance-infra",
   947  				Ports: []uint16{
   948  					80,
   949  				},
   950  			},
   951  		},
   952  		BackendServices: []*ciliumv2.Service{
   953  			{
   954  				Name:      "infra-backend-v1",
   955  				Namespace: "gateway-conformance-infra",
   956  				Ports:     []string{"8080"},
   957  			},
   958  			{
   959  				Name:      "infra-backend-v2",
   960  				Namespace: "gateway-conformance-infra",
   961  				Ports:     []string{"8080"},
   962  			},
   963  		},
   964  		Resources: []ciliumv2.XDSResource{
   965  			{Any: httpInsecureListenerXDSResource},
   966  			{
   967  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
   968  					Name: "listener-insecure",
   969  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
   970  						{
   971  							Name:    "*",
   972  							Domains: []string{"*"},
   973  							Routes: []*envoy_config_route_v3.Route{
   974  								{
   975  									Match: &envoy_config_route_v3.RouteMatch{
   976  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
   977  											Path: "/one",
   978  										},
   979  									},
   980  									Action: routeActionBackendV1,
   981  								},
   982  								{
   983  									Match: &envoy_config_route_v3.RouteMatch{
   984  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
   985  											Path: "/two",
   986  										},
   987  									},
   988  									Action: routeActionBackendV2,
   989  								},
   990  							},
   991  						},
   992  					},
   993  				}),
   994  			},
   995  			{Any: backendV1XDSResource},
   996  			{Any: backendV2XDSResource},
   997  		},
   998  	},
   999  }
  1000  
  1001  // headerMatchingHTTPListeners is the internal modal for Conformance/HTTPRouteHeaderMatching
  1002  var headerMatchingHTTPListeners = []model.HTTPListener{
  1003  	{
  1004  		Name: "http",
  1005  		Sources: []model.FullyQualifiedResource{
  1006  			{
  1007  				Name:      "same-namespace",
  1008  				Namespace: "gateway-conformance-infra",
  1009  				Group:     "gateway.networking.k8s.io",
  1010  				Version:   "v1",
  1011  				Kind:      "Gateway",
  1012  			},
  1013  		},
  1014  		Port:     80,
  1015  		Hostname: "*",
  1016  		Routes: []model.HTTPRoute{
  1017  			{
  1018  				HeadersMatch: []model.KeyValueMatch{
  1019  					{
  1020  						Key:   "version",
  1021  						Match: model.StringMatch{Exact: "one"},
  1022  					},
  1023  				},
  1024  				Backends: []model.Backend{
  1025  					{
  1026  						Name:      "infra-backend-v1",
  1027  						Namespace: "gateway-conformance-infra",
  1028  						Port: &model.BackendPort{
  1029  							Port: 8080,
  1030  						},
  1031  					},
  1032  				},
  1033  			},
  1034  			{
  1035  				HeadersMatch: []model.KeyValueMatch{
  1036  					{
  1037  						Key:   "version",
  1038  						Match: model.StringMatch{Exact: "two"},
  1039  					},
  1040  				},
  1041  				Backends: []model.Backend{
  1042  					{
  1043  						Name:      "infra-backend-v2",
  1044  						Namespace: "gateway-conformance-infra",
  1045  						Port: &model.BackendPort{
  1046  							Port: 8080,
  1047  						},
  1048  					},
  1049  				},
  1050  			},
  1051  			{
  1052  				HeadersMatch: []model.KeyValueMatch{
  1053  					{
  1054  						Key:   "version",
  1055  						Match: model.StringMatch{Exact: "two"},
  1056  					},
  1057  					{
  1058  						Key:   "color",
  1059  						Match: model.StringMatch{Exact: "orange"},
  1060  					},
  1061  				},
  1062  				Backends: []model.Backend{
  1063  					{
  1064  						Name:      "infra-backend-v1",
  1065  						Namespace: "gateway-conformance-infra",
  1066  						Port: &model.BackendPort{
  1067  							Port: 8080,
  1068  						},
  1069  					},
  1070  				},
  1071  			},
  1072  			{
  1073  				HeadersMatch: []model.KeyValueMatch{
  1074  					{
  1075  						Key:   "color",
  1076  						Match: model.StringMatch{Exact: "blue"},
  1077  					},
  1078  				},
  1079  				Backends: []model.Backend{
  1080  					{
  1081  						Name:      "infra-backend-v1",
  1082  						Namespace: "gateway-conformance-infra",
  1083  						Port: &model.BackendPort{
  1084  							Port: 8080,
  1085  						},
  1086  					},
  1087  				},
  1088  			},
  1089  			{
  1090  				HeadersMatch: []model.KeyValueMatch{
  1091  					{
  1092  						Key:   "color",
  1093  						Match: model.StringMatch{Exact: "green"},
  1094  					},
  1095  				},
  1096  				Backends: []model.Backend{
  1097  					{
  1098  						Name:      "infra-backend-v1",
  1099  						Namespace: "gateway-conformance-infra",
  1100  						Port: &model.BackendPort{
  1101  							Port: 8080,
  1102  						},
  1103  					},
  1104  				},
  1105  			},
  1106  			{
  1107  				HeadersMatch: []model.KeyValueMatch{
  1108  					{
  1109  						Key:   "color",
  1110  						Match: model.StringMatch{Exact: "red"},
  1111  					},
  1112  				},
  1113  				Backends: []model.Backend{
  1114  					{
  1115  						Name:      "infra-backend-v2",
  1116  						Namespace: "gateway-conformance-infra",
  1117  						Port: &model.BackendPort{
  1118  							Port: 8080,
  1119  						},
  1120  					},
  1121  				},
  1122  			},
  1123  			{
  1124  				HeadersMatch: []model.KeyValueMatch{
  1125  					{
  1126  						Key:   "color",
  1127  						Match: model.StringMatch{Exact: "yellow"},
  1128  					},
  1129  				},
  1130  				Backends: []model.Backend{
  1131  					{
  1132  						Name:      "infra-backend-v2",
  1133  						Namespace: "gateway-conformance-infra", Port: &model.BackendPort{
  1134  							Port: 8080,
  1135  						},
  1136  					},
  1137  				},
  1138  			},
  1139  		},
  1140  	},
  1141  }
  1142  
  1143  // headerMatchingHTTPCiliumEnvoyConfig is the generated CiliumEnvoyConfig for Conformance/HTTPRouteHeaderMatching
  1144  var headerMatchingHTTPCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  1145  	ObjectMeta: metav1.ObjectMeta{
  1146  		Name:      "cilium-gateway-same-namespace",
  1147  		Namespace: "gateway-conformance-infra",
  1148  		Labels: map[string]string{
  1149  			"cilium.io/use-original-source-address":  "false",
  1150  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  1151  		},
  1152  		OwnerReferences: []metav1.OwnerReference{
  1153  			{
  1154  				APIVersion: "gateway.networking.k8s.io/v1",
  1155  				Name:       "same-namespace",
  1156  				Kind:       "Gateway",
  1157  				Controller: model.AddressOf(true),
  1158  			},
  1159  		},
  1160  	},
  1161  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  1162  		Services: []*ciliumv2.ServiceListener{
  1163  			{
  1164  				Name:      "cilium-gateway-same-namespace",
  1165  				Namespace: "gateway-conformance-infra",
  1166  				Ports: []uint16{
  1167  					80,
  1168  				},
  1169  			},
  1170  		},
  1171  		BackendServices: []*ciliumv2.Service{
  1172  			{
  1173  				Name:      "infra-backend-v1",
  1174  				Namespace: "gateway-conformance-infra",
  1175  				Ports:     []string{"8080"},
  1176  			},
  1177  			{
  1178  				Name:      "infra-backend-v2",
  1179  				Namespace: "gateway-conformance-infra",
  1180  				Ports:     []string{"8080"},
  1181  			},
  1182  		},
  1183  		Resources: []ciliumv2.XDSResource{
  1184  			{Any: httpInsecureListenerXDSResource},
  1185  			{
  1186  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  1187  					Name: "listener-insecure",
  1188  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  1189  						{
  1190  							Name:    "*",
  1191  							Domains: []string{"*"},
  1192  							Routes: []*envoy_config_route_v3.Route{
  1193  								{
  1194  									Match: &envoy_config_route_v3.RouteMatch{
  1195  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1196  											{
  1197  												Name: "color",
  1198  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1199  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1200  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1201  															Exact: "orange",
  1202  														},
  1203  													},
  1204  												},
  1205  											},
  1206  											{
  1207  												Name: "version",
  1208  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1209  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1210  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1211  															Exact: "two",
  1212  														},
  1213  													},
  1214  												},
  1215  											},
  1216  										},
  1217  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1218  											Prefix: "/",
  1219  										},
  1220  									},
  1221  									Action: routeActionBackendV1,
  1222  								},
  1223  								{
  1224  									Match: &envoy_config_route_v3.RouteMatch{
  1225  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1226  											{
  1227  												Name: "version",
  1228  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1229  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1230  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1231  															Exact: "one",
  1232  														},
  1233  													},
  1234  												},
  1235  											},
  1236  										},
  1237  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1238  											Prefix: "/",
  1239  										},
  1240  									},
  1241  									Action: routeActionBackendV1,
  1242  								},
  1243  								{
  1244  									Match: &envoy_config_route_v3.RouteMatch{
  1245  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1246  											{
  1247  												Name: "version",
  1248  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1249  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1250  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1251  															Exact: "two",
  1252  														},
  1253  													},
  1254  												},
  1255  											},
  1256  										},
  1257  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1258  											Prefix: "/",
  1259  										},
  1260  									},
  1261  									Action: routeActionBackendV2,
  1262  								},
  1263  								{
  1264  									Match: &envoy_config_route_v3.RouteMatch{
  1265  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1266  											{
  1267  												Name: "color",
  1268  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1269  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1270  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1271  															Exact: "blue",
  1272  														},
  1273  													},
  1274  												},
  1275  											},
  1276  										},
  1277  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1278  											Prefix: "/",
  1279  										},
  1280  									},
  1281  									Action: routeActionBackendV1,
  1282  								},
  1283  								{
  1284  									Match: &envoy_config_route_v3.RouteMatch{
  1285  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1286  											{
  1287  												Name: "color",
  1288  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1289  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1290  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1291  															Exact: "green",
  1292  														},
  1293  													},
  1294  												},
  1295  											},
  1296  										},
  1297  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1298  											Prefix: "/",
  1299  										},
  1300  									},
  1301  									Action: routeActionBackendV1,
  1302  								},
  1303  								{
  1304  									Match: &envoy_config_route_v3.RouteMatch{
  1305  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1306  											{
  1307  												Name: "color",
  1308  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1309  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1310  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1311  															Exact: "red",
  1312  														},
  1313  													},
  1314  												},
  1315  											},
  1316  										},
  1317  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1318  											Prefix: "/",
  1319  										},
  1320  									},
  1321  									Action: routeActionBackendV2,
  1322  								},
  1323  								{
  1324  									Match: &envoy_config_route_v3.RouteMatch{
  1325  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1326  											{
  1327  												Name: "color",
  1328  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1329  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1330  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1331  															Exact: "yellow",
  1332  														},
  1333  													},
  1334  												},
  1335  											},
  1336  										},
  1337  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1338  											Prefix: "/",
  1339  										},
  1340  									},
  1341  									Action: routeActionBackendV2,
  1342  								},
  1343  							},
  1344  						},
  1345  					},
  1346  				}),
  1347  			},
  1348  			{Any: backendV1XDSResource},
  1349  			{Any: backendV2XDSResource},
  1350  		},
  1351  	},
  1352  }
  1353  
  1354  // hostnameIntersectionHTTPListeners is a internal model representation of the Conformance/HTTPRouteHostnameIntersection
  1355  var hostnameIntersectionHTTPListeners = []model.HTTPListener{
  1356  	{
  1357  		Name: "listener-1",
  1358  		Sources: []model.FullyQualifiedResource{
  1359  			{
  1360  				Name:      "httproute-hostname-intersection",
  1361  				Namespace: "gateway-conformance-infra",
  1362  				Group:     "gateway.networking.k8s.io",
  1363  				Version:   "v1",
  1364  				Kind:      "Gateway",
  1365  			},
  1366  		},
  1367  		Port:     80,
  1368  		Hostname: "very.specific.com",
  1369  		Routes: []model.HTTPRoute{
  1370  			{
  1371  				Hostnames: []string{"very.specific.com"},
  1372  				PathMatch: model.StringMatch{Prefix: "/s1"},
  1373  				Backends: []model.Backend{
  1374  					{
  1375  						Name:      "infra-backend-v1",
  1376  						Namespace: "gateway-conformance-infra",
  1377  						Port: &model.BackendPort{
  1378  							Port: 8080,
  1379  						},
  1380  					},
  1381  				},
  1382  			},
  1383  			{
  1384  				Hostnames: []string{"very.specific.com"},
  1385  				PathMatch: model.StringMatch{Prefix: "/s3"},
  1386  				Backends: []model.Backend{
  1387  					{
  1388  						Name:      "infra-backend-v3",
  1389  						Namespace: "gateway-conformance-infra",
  1390  						Port: &model.BackendPort{
  1391  							Port: 8080,
  1392  						},
  1393  					},
  1394  				},
  1395  			},
  1396  		},
  1397  	},
  1398  	{
  1399  		Name: "listener-2",
  1400  		Sources: []model.FullyQualifiedResource{
  1401  			{
  1402  				Namespace: "gateway-conformance-infra",
  1403  				Name:      "httproute-hostname-intersection",
  1404  				Group:     "gateway.networking.k8s.io",
  1405  				Version:   "v1",
  1406  				Kind:      "Gateway",
  1407  			},
  1408  		},
  1409  		Port:     80,
  1410  		Hostname: "*.wildcard.io",
  1411  		Routes: []model.HTTPRoute{
  1412  			{
  1413  				Hostnames: []string{"bar.wildcard.io", "foo.bar.wildcard.io", "foo.wildcard.io"},
  1414  				PathMatch: model.StringMatch{Prefix: "/s2"},
  1415  				Backends: []model.Backend{
  1416  					{
  1417  						Name:      "infra-backend-v2",
  1418  						Namespace: "gateway-conformance-infra",
  1419  						Port: &model.BackendPort{
  1420  							Port: 8080,
  1421  						},
  1422  					},
  1423  				},
  1424  			},
  1425  		},
  1426  	},
  1427  	{
  1428  		Name: "listener-3",
  1429  		Sources: []model.FullyQualifiedResource{
  1430  			{
  1431  				Name:      "httproute-hostname-intersection",
  1432  				Namespace: "gateway-conformance-infra",
  1433  				Group:     "gateway.networking.k8s.io",
  1434  				Version:   "v1",
  1435  				Kind:      "Gateway",
  1436  			},
  1437  		},
  1438  		Port:     80,
  1439  		Hostname: "*.anotherwildcard.io",
  1440  		Routes: []model.HTTPRoute{
  1441  			{
  1442  				Hostnames: []string{"*.anotherwildcard.io"},
  1443  				PathMatch: model.StringMatch{Prefix: "/s4"},
  1444  				Backends: []model.Backend{
  1445  					{
  1446  						Name:      "infra-backend-v1",
  1447  						Namespace: "gateway-conformance-infra",
  1448  						Port: &model.BackendPort{
  1449  							Port: 8080,
  1450  						},
  1451  					},
  1452  				},
  1453  			},
  1454  		},
  1455  	},
  1456  }
  1457  
  1458  var hostnameIntersectionHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  1459  	ObjectMeta: metav1.ObjectMeta{
  1460  		Name:      "cilium-gateway-httproute-hostname-intersection",
  1461  		Namespace: "gateway-conformance-infra",
  1462  		Labels: map[string]string{
  1463  			"cilium.io/use-original-source-address":  "false",
  1464  			"gateway.networking.k8s.io/gateway-name": "httproute-hostname-intersection",
  1465  		},
  1466  		OwnerReferences: []metav1.OwnerReference{
  1467  			{
  1468  				APIVersion: "gateway.networking.k8s.io/v1",
  1469  				Kind:       "Gateway",
  1470  				Name:       "httproute-hostname-intersection",
  1471  				Controller: model.AddressOf(true),
  1472  			},
  1473  		},
  1474  	},
  1475  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  1476  		Services: []*ciliumv2.ServiceListener{
  1477  			{
  1478  				Name:      "cilium-gateway-httproute-hostname-intersection",
  1479  				Namespace: "gateway-conformance-infra",
  1480  				Ports: []uint16{
  1481  					80,
  1482  				},
  1483  			},
  1484  		},
  1485  		BackendServices: []*ciliumv2.Service{
  1486  			{
  1487  				Name:      "infra-backend-v1",
  1488  				Namespace: "gateway-conformance-infra",
  1489  				Ports:     []string{"8080"},
  1490  			},
  1491  			{
  1492  				Name:      "infra-backend-v2",
  1493  				Namespace: "gateway-conformance-infra",
  1494  				Ports:     []string{"8080"},
  1495  			},
  1496  			{
  1497  				Name:      "infra-backend-v3",
  1498  				Namespace: "gateway-conformance-infra",
  1499  				Ports:     []string{"8080"},
  1500  			},
  1501  		},
  1502  		Resources: []ciliumv2.XDSResource{
  1503  			{Any: httpInsecureListenerXDSResource},
  1504  			{
  1505  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  1506  					Name: "listener-insecure",
  1507  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  1508  						{
  1509  							Name:    "*.anotherwildcard.io",
  1510  							Domains: []string{"*.anotherwildcard.io", "*.anotherwildcard.io:*"},
  1511  							Routes: []*envoy_config_route_v3.Route{
  1512  								{
  1513  									Match: &envoy_config_route_v3.RouteMatch{
  1514  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  1515  											PathSeparatedPrefix: "/s4",
  1516  										},
  1517  									},
  1518  									Action: routeActionBackendV1,
  1519  								},
  1520  							},
  1521  						},
  1522  						{
  1523  							Name:    "bar.wildcard.io",
  1524  							Domains: []string{"bar.wildcard.io", "bar.wildcard.io:*"},
  1525  							Routes: []*envoy_config_route_v3.Route{
  1526  								{
  1527  									Match: &envoy_config_route_v3.RouteMatch{
  1528  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  1529  											PathSeparatedPrefix: "/s2",
  1530  										},
  1531  									},
  1532  									Action: routeActionBackendV2,
  1533  								},
  1534  							},
  1535  						},
  1536  						{
  1537  							Name:    "foo.bar.wildcard.io",
  1538  							Domains: []string{"foo.bar.wildcard.io", "foo.bar.wildcard.io:*"},
  1539  							Routes: []*envoy_config_route_v3.Route{
  1540  								{
  1541  									Match: &envoy_config_route_v3.RouteMatch{
  1542  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  1543  											PathSeparatedPrefix: "/s2",
  1544  										},
  1545  									},
  1546  									Action: routeActionBackendV2,
  1547  								},
  1548  							},
  1549  						},
  1550  						{
  1551  							Name:    "foo.wildcard.io",
  1552  							Domains: []string{"foo.wildcard.io", "foo.wildcard.io:*"},
  1553  							Routes: []*envoy_config_route_v3.Route{
  1554  								{
  1555  									Match: &envoy_config_route_v3.RouteMatch{
  1556  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  1557  											PathSeparatedPrefix: "/s2",
  1558  										},
  1559  									},
  1560  									Action: routeActionBackendV2,
  1561  								},
  1562  							},
  1563  						},
  1564  						{
  1565  							Name:    "very.specific.com",
  1566  							Domains: []string{"very.specific.com", "very.specific.com:*"},
  1567  							Routes: []*envoy_config_route_v3.Route{
  1568  								{
  1569  									Match: &envoy_config_route_v3.RouteMatch{
  1570  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  1571  											PathSeparatedPrefix: "/s1",
  1572  										},
  1573  									},
  1574  									Action: routeActionBackendV1,
  1575  								},
  1576  								{
  1577  									Match: &envoy_config_route_v3.RouteMatch{
  1578  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  1579  											PathSeparatedPrefix: "/s3",
  1580  										},
  1581  									},
  1582  									Action: routeActionBackendV3,
  1583  								},
  1584  							},
  1585  						},
  1586  					},
  1587  				}),
  1588  			},
  1589  			{Any: backendV1XDSResource},
  1590  			{Any: backendV2XDSResource},
  1591  			{Any: backendV3XDSResource},
  1592  		},
  1593  	},
  1594  }
  1595  
  1596  // listenerHostnameMatchingHTTPListeners are the internal model for Conformance/HTTPRouteListenerHostnameMatching
  1597  var listenerHostnameMatchingHTTPListeners = []model.HTTPListener{
  1598  	{
  1599  		Name: "listener-1",
  1600  		Sources: []model.FullyQualifiedResource{
  1601  			{
  1602  				Name:      "httproute-listener-hostname-matching",
  1603  				Namespace: "gateway-conformance-infra",
  1604  				Group:     "gateway.networking.k8s.io",
  1605  				Version:   "v1",
  1606  				Kind:      "Gateway",
  1607  			},
  1608  		},
  1609  		Port:     80,
  1610  		Hostname: "bar.com",
  1611  		Routes: []model.HTTPRoute{
  1612  			{
  1613  				Hostnames: []string{"bar.com"},
  1614  				Backends: []model.Backend{
  1615  					{
  1616  						Name:      "infra-backend-v1",
  1617  						Namespace: "gateway-conformance-infra",
  1618  						Port: &model.BackendPort{
  1619  							Port: 8080,
  1620  						},
  1621  					},
  1622  				},
  1623  			},
  1624  		},
  1625  	},
  1626  	{
  1627  		Name: "listener-2",
  1628  		Sources: []model.FullyQualifiedResource{
  1629  			{
  1630  				Name:      "httproute-listener-hostname-matching",
  1631  				Namespace: "gateway-conformance-infra",
  1632  				Group:     "gateway.networking.k8s.io",
  1633  				Version:   "v1",
  1634  				Kind:      "Gateway",
  1635  			},
  1636  		},
  1637  		Port:     80,
  1638  		Hostname: "foo.bar.com",
  1639  		Routes: []model.HTTPRoute{
  1640  			{
  1641  				Hostnames: []string{"foo.bar.com"},
  1642  				Backends: []model.Backend{
  1643  					{
  1644  						Name:      "infra-backend-v2",
  1645  						Namespace: "gateway-conformance-infra",
  1646  						Port: &model.BackendPort{
  1647  							Port: 8080,
  1648  						},
  1649  					},
  1650  				},
  1651  			},
  1652  		},
  1653  	},
  1654  	{
  1655  		Name: "listener-3",
  1656  		Sources: []model.FullyQualifiedResource{
  1657  			{
  1658  				Name:      "httproute-listener-hostname-matching",
  1659  				Namespace: "gateway-conformance-infra",
  1660  				Group:     "gateway.networking.k8s.io",
  1661  				Version:   "v1",
  1662  				Kind:      "Gateway",
  1663  			},
  1664  		},
  1665  		Port:     80,
  1666  		Hostname: "*.bar.com",
  1667  		Routes: []model.HTTPRoute{
  1668  			{
  1669  				Hostnames: []string{"*.bar.com"},
  1670  				Backends: []model.Backend{
  1671  					{
  1672  						Name:      "infra-backend-v3",
  1673  						Namespace: "gateway-conformance-infra",
  1674  						Port: &model.BackendPort{
  1675  							Port: 8080,
  1676  						},
  1677  					},
  1678  				},
  1679  			},
  1680  		},
  1681  	},
  1682  	{
  1683  		Name: "listener-4",
  1684  		Sources: []model.FullyQualifiedResource{
  1685  			{
  1686  				Name:      "httproute-listener-hostname-matching",
  1687  				Namespace: "gateway-conformance-infra",
  1688  				Group:     "gateway.networking.k8s.io",
  1689  				Version:   "v1",
  1690  				Kind:      "Gateway",
  1691  			},
  1692  		},
  1693  		Port:     80,
  1694  		Hostname: "*.foo.com",
  1695  		Routes: []model.HTTPRoute{
  1696  			{
  1697  				Hostnames: []string{"*.foo.com"},
  1698  				Backends: []model.Backend{
  1699  					{
  1700  						Name:      "infra-backend-v3",
  1701  						Namespace: "gateway-conformance-infra",
  1702  						Port: &model.BackendPort{
  1703  							Port: 8080,
  1704  						},
  1705  					},
  1706  				},
  1707  			},
  1708  		},
  1709  	},
  1710  }
  1711  
  1712  // listenerHostNameMatchingCiliumEnvoyConfig is the generated CiliumEnvoyConfig for Conformance/HTTPRouteListenerHostnameMatching
  1713  var listenerHostNameMatchingCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  1714  	ObjectMeta: metav1.ObjectMeta{
  1715  		Name:      "cilium-gateway-httproute-listener-hostname-matching",
  1716  		Namespace: "gateway-conformance-infra",
  1717  		Labels: map[string]string{
  1718  			"cilium.io/use-original-source-address":  "false",
  1719  			"gateway.networking.k8s.io/gateway-name": "httproute-listener-hostname-matching",
  1720  		},
  1721  		OwnerReferences: []metav1.OwnerReference{
  1722  			{
  1723  				APIVersion: "gateway.networking.k8s.io/v1",
  1724  				Kind:       "Gateway",
  1725  				Name:       "httproute-listener-hostname-matching",
  1726  				Controller: model.AddressOf(true),
  1727  			},
  1728  		},
  1729  	},
  1730  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  1731  		Services: []*ciliumv2.ServiceListener{
  1732  			{
  1733  				Name:      "cilium-gateway-httproute-listener-hostname-matching",
  1734  				Namespace: "gateway-conformance-infra",
  1735  				Ports: []uint16{
  1736  					80,
  1737  				},
  1738  			},
  1739  		},
  1740  		BackendServices: []*ciliumv2.Service{
  1741  			{
  1742  				Name:      "infra-backend-v1",
  1743  				Namespace: "gateway-conformance-infra",
  1744  				Ports:     []string{"8080"},
  1745  			},
  1746  			{
  1747  				Name:      "infra-backend-v2",
  1748  				Namespace: "gateway-conformance-infra",
  1749  				Ports:     []string{"8080"},
  1750  			},
  1751  			{
  1752  				Name:      "infra-backend-v3",
  1753  				Namespace: "gateway-conformance-infra",
  1754  				Ports:     []string{"8080"},
  1755  			},
  1756  		},
  1757  		Resources: []ciliumv2.XDSResource{
  1758  			{Any: httpInsecureListenerXDSResource},
  1759  			{
  1760  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  1761  					Name: "listener-insecure",
  1762  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  1763  						{
  1764  							Name:    "*.bar.com",
  1765  							Domains: []string{"*.bar.com", "*.bar.com:*"},
  1766  							Routes: []*envoy_config_route_v3.Route{
  1767  								{
  1768  									Match: &envoy_config_route_v3.RouteMatch{
  1769  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1770  											Prefix: "/",
  1771  										},
  1772  									},
  1773  									Action: routeActionBackendV3,
  1774  								},
  1775  							},
  1776  						},
  1777  						{
  1778  							Name:    "*.foo.com",
  1779  							Domains: []string{"*.foo.com", "*.foo.com:*"},
  1780  							Routes: []*envoy_config_route_v3.Route{
  1781  								{
  1782  									Match: &envoy_config_route_v3.RouteMatch{
  1783  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1784  											Prefix: "/",
  1785  										},
  1786  									},
  1787  									Action: routeActionBackendV3,
  1788  								},
  1789  							},
  1790  						},
  1791  						{
  1792  							Name:    "bar.com",
  1793  							Domains: []string{"bar.com", "bar.com:*"},
  1794  							Routes: []*envoy_config_route_v3.Route{
  1795  								{
  1796  									Match: &envoy_config_route_v3.RouteMatch{
  1797  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1798  											Prefix: "/",
  1799  										},
  1800  									},
  1801  									Action: routeActionBackendV1,
  1802  								},
  1803  							},
  1804  						},
  1805  						{
  1806  							Name:    "foo.bar.com",
  1807  							Domains: []string{"foo.bar.com", "foo.bar.com:*"},
  1808  							Routes: []*envoy_config_route_v3.Route{
  1809  								{
  1810  									Match: &envoy_config_route_v3.RouteMatch{
  1811  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  1812  											Prefix: "/",
  1813  										},
  1814  									},
  1815  									Action: routeActionBackendV2,
  1816  								},
  1817  							},
  1818  						},
  1819  					},
  1820  				}),
  1821  			},
  1822  			{Any: backendV1XDSResource},
  1823  			{Any: backendV2XDSResource},
  1824  			{Any: backendV3XDSResource},
  1825  		},
  1826  	},
  1827  }
  1828  
  1829  // matchingAcrossHTTPListeners is the internal model for Conformance/HTTPRouteMatchingAcrossHTTPListeners
  1830  var matchingAcrossHTTPListeners = []model.HTTPListener{
  1831  	{
  1832  		Name: "http",
  1833  		Sources: []model.FullyQualifiedResource{
  1834  			{
  1835  				Name:      "same-namespace",
  1836  				Namespace: "gateway-conformance-infra",
  1837  				Group:     "gateway.networking.k8s.io",
  1838  				Version:   "v1",
  1839  				Kind:      "Gateway",
  1840  			},
  1841  		},
  1842  		Port:     80,
  1843  		Hostname: "*",
  1844  		Routes: []model.HTTPRoute{
  1845  			{
  1846  				Hostnames: []string{"example.com", "example.net"},
  1847  				PathMatch: model.StringMatch{Exact: "/"},
  1848  				HeadersMatch: []model.KeyValueMatch{
  1849  					{
  1850  						Key:   "version",
  1851  						Match: model.StringMatch{Exact: "one"},
  1852  					},
  1853  				},
  1854  				Backends: []model.Backend{
  1855  					{
  1856  						Name:      "infra-backend-v1",
  1857  						Namespace: "gateway-conformance-infra",
  1858  						Port: &model.BackendPort{
  1859  							Port: 8080,
  1860  						},
  1861  					},
  1862  				},
  1863  			},
  1864  			{
  1865  				Hostnames:    []string{"example.com"},
  1866  				PathMatch:    model.StringMatch{Exact: "/v2"},
  1867  				HeadersMatch: []model.KeyValueMatch{{Key: "version", Match: model.StringMatch{Exact: "two"}}},
  1868  				Backends: []model.Backend{
  1869  					{
  1870  						Name:      "infra-backend-v2",
  1871  						Namespace: "gateway-conformance-infra",
  1872  						Port: &model.BackendPort{
  1873  							Port: 8080,
  1874  						},
  1875  					},
  1876  				},
  1877  			},
  1878  		},
  1879  	},
  1880  }
  1881  
  1882  var matchingAcrossHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  1883  	ObjectMeta: metav1.ObjectMeta{
  1884  		Name:      "cilium-gateway-same-namespace",
  1885  		Namespace: "gateway-conformance-infra",
  1886  		Labels: map[string]string{
  1887  			"cilium.io/use-original-source-address":  "false",
  1888  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  1889  		},
  1890  		OwnerReferences: []metav1.OwnerReference{
  1891  			{
  1892  				APIVersion: "gateway.networking.k8s.io/v1",
  1893  				Kind:       "Gateway",
  1894  				Name:       "same-namespace",
  1895  				Controller: model.AddressOf(true),
  1896  			},
  1897  		},
  1898  	},
  1899  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  1900  		Services: []*ciliumv2.ServiceListener{
  1901  			{
  1902  				Name:      "cilium-gateway-same-namespace",
  1903  				Namespace: "gateway-conformance-infra",
  1904  				Ports: []uint16{
  1905  					80,
  1906  				},
  1907  			},
  1908  		},
  1909  		BackendServices: []*ciliumv2.Service{
  1910  			{
  1911  				Name:      "infra-backend-v1",
  1912  				Namespace: "gateway-conformance-infra",
  1913  				Ports:     []string{"8080"},
  1914  			},
  1915  			{
  1916  				Name:      "infra-backend-v2",
  1917  				Namespace: "gateway-conformance-infra",
  1918  				Ports:     []string{"8080"},
  1919  			},
  1920  		},
  1921  		Resources: []ciliumv2.XDSResource{
  1922  			{Any: httpInsecureListenerXDSResource},
  1923  			{
  1924  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  1925  					Name: "listener-insecure",
  1926  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  1927  						{
  1928  							Name:    "example.com",
  1929  							Domains: []string{"example.com", "example.com:*"},
  1930  							Routes: []*envoy_config_route_v3.Route{
  1931  								{
  1932  									Match: &envoy_config_route_v3.RouteMatch{
  1933  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  1934  											Path: "/v2",
  1935  										},
  1936  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1937  											{
  1938  												Name: "version",
  1939  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1940  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1941  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1942  															Exact: "two",
  1943  														},
  1944  													},
  1945  												},
  1946  											},
  1947  										},
  1948  									},
  1949  									Action: routeActionBackendV2,
  1950  								},
  1951  								{
  1952  									Match: &envoy_config_route_v3.RouteMatch{
  1953  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  1954  											Path: "/",
  1955  										},
  1956  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1957  											{
  1958  												Name: "version",
  1959  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1960  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1961  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1962  															Exact: "one",
  1963  														},
  1964  													},
  1965  												},
  1966  											},
  1967  										},
  1968  									},
  1969  									Action: routeActionBackendV1,
  1970  								},
  1971  							},
  1972  						},
  1973  
  1974  						{
  1975  							Name:    "example.net",
  1976  							Domains: []string{"example.net", "example.net:*"},
  1977  							Routes: []*envoy_config_route_v3.Route{
  1978  								{
  1979  									Match: &envoy_config_route_v3.RouteMatch{
  1980  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  1981  											Path: "/",
  1982  										},
  1983  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  1984  											{
  1985  												Name: "version",
  1986  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  1987  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  1988  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  1989  															Exact: "one",
  1990  														},
  1991  													},
  1992  												},
  1993  											},
  1994  										},
  1995  									},
  1996  									Action: routeActionBackendV1,
  1997  								},
  1998  							},
  1999  						},
  2000  					},
  2001  				}),
  2002  			},
  2003  			{Any: backendV1XDSResource},
  2004  			{Any: backendV2XDSResource},
  2005  		},
  2006  	},
  2007  }
  2008  
  2009  // matchingHTTPListeners is the internal model for Conformance/HTTPRouteMatching
  2010  var matchingHTTPListeners = []model.HTTPListener{
  2011  	{
  2012  		Name: "http",
  2013  		Sources: []model.FullyQualifiedResource{
  2014  			{
  2015  				Name:      "same-namespace",
  2016  				Namespace: "gateway-conformance-infra",
  2017  				Group:     "gateway.networking.k8s.io",
  2018  				Version:   "v1",
  2019  				Kind:      "Gateway",
  2020  			},
  2021  		},
  2022  		Port: 80, Hostname: "*",
  2023  		Routes: []model.HTTPRoute{
  2024  			{
  2025  				PathMatch: model.StringMatch{Exact: "/"},
  2026  				HeadersMatch: []model.KeyValueMatch{
  2027  					{
  2028  						Key:   "version",
  2029  						Match: model.StringMatch{Exact: "one"},
  2030  					},
  2031  				},
  2032  				Backends: []model.Backend{
  2033  					{
  2034  						Name:      "infra-backend-v1",
  2035  						Namespace: "gateway-conformance-infra",
  2036  						Port: &model.BackendPort{
  2037  							Port: 8080,
  2038  						},
  2039  					},
  2040  				},
  2041  			},
  2042  			{
  2043  				PathMatch: model.StringMatch{Exact: "/v2"},
  2044  				HeadersMatch: []model.KeyValueMatch{
  2045  					{
  2046  						Key:   "version",
  2047  						Match: model.StringMatch{Exact: "two"},
  2048  					},
  2049  				},
  2050  				Backends: []model.Backend{
  2051  					{
  2052  						Name:      "infra-backend-v2",
  2053  						Namespace: "gateway-conformance-infra",
  2054  						Port: &model.BackendPort{
  2055  							Port: 8080,
  2056  						},
  2057  					},
  2058  				},
  2059  			},
  2060  		},
  2061  	},
  2062  }
  2063  
  2064  var matchingHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  2065  	ObjectMeta: metav1.ObjectMeta{
  2066  		Name:      "cilium-gateway-same-namespace",
  2067  		Namespace: "gateway-conformance-infra",
  2068  		Labels: map[string]string{
  2069  			"cilium.io/use-original-source-address":  "false",
  2070  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  2071  		},
  2072  		OwnerReferences: []metav1.OwnerReference{
  2073  			{
  2074  				APIVersion: "gateway.networking.k8s.io/v1",
  2075  				Kind:       "Gateway",
  2076  				Name:       "same-namespace",
  2077  				Controller: model.AddressOf(true),
  2078  			},
  2079  		},
  2080  	},
  2081  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  2082  		Services: []*ciliumv2.ServiceListener{
  2083  			{
  2084  				Name:      "cilium-gateway-same-namespace",
  2085  				Namespace: "gateway-conformance-infra",
  2086  				Ports: []uint16{
  2087  					80,
  2088  				},
  2089  			},
  2090  		},
  2091  		BackendServices: []*ciliumv2.Service{
  2092  			{
  2093  				Name:      "infra-backend-v1",
  2094  				Namespace: "gateway-conformance-infra",
  2095  				Ports:     []string{"8080"},
  2096  			},
  2097  			{
  2098  				Name:      "infra-backend-v2",
  2099  				Namespace: "gateway-conformance-infra",
  2100  				Ports:     []string{"8080"},
  2101  			},
  2102  		},
  2103  		Resources: []ciliumv2.XDSResource{
  2104  			{Any: httpInsecureListenerXDSResource},
  2105  			{
  2106  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  2107  					Name: "listener-insecure",
  2108  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  2109  						{
  2110  							Name:    "*",
  2111  							Domains: []string{"*"},
  2112  							Routes: []*envoy_config_route_v3.Route{
  2113  								{
  2114  									Match: &envoy_config_route_v3.RouteMatch{
  2115  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  2116  											Path: "/v2",
  2117  										},
  2118  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  2119  											{
  2120  												Name: "version",
  2121  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  2122  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2123  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2124  															Exact: "two",
  2125  														},
  2126  													},
  2127  												},
  2128  											},
  2129  										},
  2130  									},
  2131  									Action: routeActionBackendV2,
  2132  								},
  2133  								{
  2134  									Match: &envoy_config_route_v3.RouteMatch{
  2135  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  2136  											Path: "/",
  2137  										},
  2138  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  2139  											{
  2140  												Name: "version",
  2141  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  2142  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2143  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2144  															Exact: "one",
  2145  														},
  2146  													},
  2147  												},
  2148  											},
  2149  										},
  2150  									},
  2151  									Action: routeActionBackendV1,
  2152  								},
  2153  							},
  2154  						},
  2155  					},
  2156  				}),
  2157  			},
  2158  			{Any: backendV1XDSResource},
  2159  			{Any: backendV2XDSResource},
  2160  		},
  2161  	},
  2162  }
  2163  
  2164  // queryParamMatchingHTTPListeners is the internal model for Conformance/HTTPRouteQueryParamMatching
  2165  var queryParamMatchingHTTPListeners = []model.HTTPListener{
  2166  	{
  2167  		Name: "http",
  2168  		Sources: []model.FullyQualifiedResource{
  2169  			{
  2170  				Name:      "same-namespace",
  2171  				Namespace: "gateway-conformance-infra",
  2172  				Group:     "gateway.networking.k8s.io",
  2173  				Version:   "v1",
  2174  				Kind:      "Gateway",
  2175  			},
  2176  		},
  2177  		Port:     80,
  2178  		Hostname: "*",
  2179  		Routes: []model.HTTPRoute{
  2180  			{
  2181  				QueryParamsMatch: []model.KeyValueMatch{
  2182  					{
  2183  						Key:   "animal",
  2184  						Match: model.StringMatch{Exact: "whale"},
  2185  					},
  2186  				},
  2187  				Backends: []model.Backend{
  2188  					{
  2189  						Name:      "infra-backend-v1",
  2190  						Namespace: "gateway-conformance-infra",
  2191  						Port: &model.BackendPort{
  2192  							Port: 8080,
  2193  						},
  2194  					},
  2195  				},
  2196  			},
  2197  			{
  2198  				QueryParamsMatch: []model.KeyValueMatch{
  2199  					{
  2200  						Key:   "animal",
  2201  						Match: model.StringMatch{Exact: "dolphin"},
  2202  					},
  2203  				},
  2204  				Backends: []model.Backend{
  2205  					{
  2206  						Name:      "infra-backend-v2",
  2207  						Namespace: "gateway-conformance-infra",
  2208  						Port: &model.BackendPort{
  2209  							Port: 8080,
  2210  						},
  2211  					},
  2212  				},
  2213  			},
  2214  			{
  2215  				QueryParamsMatch: []model.KeyValueMatch{
  2216  					{
  2217  						Key:   "animal",
  2218  						Match: model.StringMatch{Exact: "dolphin"},
  2219  					},
  2220  					{
  2221  						Key:   "color",
  2222  						Match: model.StringMatch{Exact: "blue"},
  2223  					},
  2224  				},
  2225  				Backends: []model.Backend{
  2226  					{
  2227  						Name:      "infra-backend-v3",
  2228  						Namespace: "gateway-conformance-infra",
  2229  						Port: &model.BackendPort{
  2230  							Port: 8080,
  2231  						},
  2232  					},
  2233  				},
  2234  			},
  2235  			{
  2236  				QueryParamsMatch: []model.KeyValueMatch{
  2237  					{
  2238  						Key:   "ANIMAL",
  2239  						Match: model.StringMatch{Exact: "Whale"},
  2240  					},
  2241  				},
  2242  				Backends: []model.Backend{
  2243  					{
  2244  						Name:      "infra-backend-v3",
  2245  						Namespace: "gateway-conformance-infra",
  2246  						Port: &model.BackendPort{
  2247  							Port: 8080,
  2248  						},
  2249  					},
  2250  				},
  2251  			},
  2252  		},
  2253  	},
  2254  }
  2255  
  2256  var queryParamMatchingHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  2257  	ObjectMeta: metav1.ObjectMeta{
  2258  		Name:      "cilium-gateway-same-namespace",
  2259  		Namespace: "gateway-conformance-infra",
  2260  		Labels: map[string]string{
  2261  			"cilium.io/use-original-source-address":  "false",
  2262  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  2263  		},
  2264  		OwnerReferences: []metav1.OwnerReference{
  2265  			{
  2266  				APIVersion: "gateway.networking.k8s.io/v1",
  2267  				Kind:       "Gateway",
  2268  				Name:       "same-namespace",
  2269  				Controller: model.AddressOf(true),
  2270  			},
  2271  		},
  2272  	},
  2273  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  2274  		Services: []*ciliumv2.ServiceListener{
  2275  			{
  2276  				Name:      "cilium-gateway-same-namespace",
  2277  				Namespace: "gateway-conformance-infra",
  2278  				Ports: []uint16{
  2279  					80,
  2280  				},
  2281  			},
  2282  		},
  2283  		BackendServices: []*ciliumv2.Service{
  2284  			{
  2285  				Name:      "infra-backend-v1",
  2286  				Namespace: "gateway-conformance-infra",
  2287  				Ports:     []string{"8080"},
  2288  			},
  2289  			{
  2290  				Name:      "infra-backend-v2",
  2291  				Namespace: "gateway-conformance-infra",
  2292  				Ports:     []string{"8080"},
  2293  			},
  2294  			{
  2295  				Name:      "infra-backend-v3",
  2296  				Namespace: "gateway-conformance-infra",
  2297  				Ports:     []string{"8080"},
  2298  			},
  2299  		},
  2300  		Resources: []ciliumv2.XDSResource{
  2301  			{Any: httpInsecureListenerXDSResource},
  2302  			{
  2303  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  2304  					Name: "listener-insecure",
  2305  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  2306  						{
  2307  							Name:    "*",
  2308  							Domains: []string{"*"},
  2309  							Routes: []*envoy_config_route_v3.Route{
  2310  								{
  2311  									Match: &envoy_config_route_v3.RouteMatch{
  2312  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  2313  											Prefix: "/",
  2314  										},
  2315  										QueryParameters: []*envoy_config_route_v3.QueryParameterMatcher{
  2316  											{
  2317  												Name: "animal",
  2318  												QueryParameterMatchSpecifier: &envoy_config_route_v3.QueryParameterMatcher_StringMatch{
  2319  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2320  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2321  															Exact: "dolphin",
  2322  														},
  2323  													},
  2324  												},
  2325  											},
  2326  											{
  2327  												Name: "color",
  2328  												QueryParameterMatchSpecifier: &envoy_config_route_v3.QueryParameterMatcher_StringMatch{
  2329  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2330  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2331  															Exact: "blue",
  2332  														},
  2333  													},
  2334  												},
  2335  											},
  2336  										},
  2337  									},
  2338  									Action: routeActionBackendV3,
  2339  								},
  2340  								{
  2341  									Match: &envoy_config_route_v3.RouteMatch{
  2342  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  2343  											Prefix: "/",
  2344  										},
  2345  										QueryParameters: []*envoy_config_route_v3.QueryParameterMatcher{
  2346  											{
  2347  												Name: "animal",
  2348  												QueryParameterMatchSpecifier: &envoy_config_route_v3.QueryParameterMatcher_StringMatch{
  2349  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2350  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2351  															Exact: "whale",
  2352  														},
  2353  													},
  2354  												},
  2355  											},
  2356  										},
  2357  									},
  2358  									Action: routeActionBackendV1,
  2359  								},
  2360  								{
  2361  									Match: &envoy_config_route_v3.RouteMatch{
  2362  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  2363  											Prefix: "/",
  2364  										},
  2365  										QueryParameters: []*envoy_config_route_v3.QueryParameterMatcher{
  2366  											{
  2367  												Name: "animal",
  2368  												QueryParameterMatchSpecifier: &envoy_config_route_v3.QueryParameterMatcher_StringMatch{
  2369  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2370  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2371  															Exact: "dolphin",
  2372  														},
  2373  													},
  2374  												},
  2375  											},
  2376  										},
  2377  									},
  2378  									Action: routeActionBackendV2,
  2379  								},
  2380  								{
  2381  									Match: &envoy_config_route_v3.RouteMatch{
  2382  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  2383  											Prefix: "/",
  2384  										},
  2385  										QueryParameters: []*envoy_config_route_v3.QueryParameterMatcher{
  2386  											{
  2387  												Name: "ANIMAL",
  2388  												QueryParameterMatchSpecifier: &envoy_config_route_v3.QueryParameterMatcher_StringMatch{
  2389  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2390  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2391  															Exact: "Whale",
  2392  														},
  2393  													},
  2394  												},
  2395  											},
  2396  										},
  2397  									},
  2398  									Action: routeActionBackendV3,
  2399  								},
  2400  							},
  2401  						},
  2402  					},
  2403  				}),
  2404  			},
  2405  			{Any: backendV1XDSResource},
  2406  			{Any: backendV2XDSResource},
  2407  			{Any: backendV3XDSResource},
  2408  		},
  2409  	},
  2410  }
  2411  
  2412  // methodMatchingHTTPListeners is the internal representation of the Conformance/HTTPRouteMethodMatching
  2413  var methodMatchingHTTPListeners = []model.HTTPListener{
  2414  	{
  2415  		Name: "http",
  2416  		Sources: []model.FullyQualifiedResource{
  2417  			{
  2418  				Name:      "same-namespace",
  2419  				Namespace: "gateway-conformance-infra",
  2420  				Group:     "gateway.networking.k8s.io",
  2421  				Version:   "v1",
  2422  				Kind:      "Gateway",
  2423  			},
  2424  		},
  2425  		Port:     80,
  2426  		Hostname: "*",
  2427  		Routes: []model.HTTPRoute{
  2428  			{
  2429  				Method: model.AddressOf("POST"),
  2430  				Backends: []model.Backend{
  2431  					{
  2432  						Name:      "infra-backend-v1",
  2433  						Namespace: "gateway-conformance-infra",
  2434  						Port: &model.BackendPort{
  2435  							Port: 8080,
  2436  						},
  2437  					},
  2438  				},
  2439  			},
  2440  			{
  2441  				Method: model.AddressOf("GET"),
  2442  				Backends: []model.Backend{
  2443  					{
  2444  						Name:      "infra-backend-v2",
  2445  						Namespace: "gateway-conformance-infra",
  2446  						Port: &model.BackendPort{
  2447  							Port: 8080,
  2448  						},
  2449  					},
  2450  				},
  2451  			},
  2452  		},
  2453  	},
  2454  }
  2455  
  2456  var methodMatchingHTTPListenersHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  2457  	ObjectMeta: metav1.ObjectMeta{
  2458  		Name:      "cilium-gateway-same-namespace",
  2459  		Namespace: "gateway-conformance-infra",
  2460  		Labels: map[string]string{
  2461  			"cilium.io/use-original-source-address":  "false",
  2462  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  2463  		},
  2464  		OwnerReferences: []metav1.OwnerReference{
  2465  			{
  2466  				APIVersion: "gateway.networking.k8s.io/v1",
  2467  				Kind:       "Gateway",
  2468  				Name:       "same-namespace",
  2469  				Controller: model.AddressOf(true),
  2470  			},
  2471  		},
  2472  	},
  2473  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  2474  		Services: []*ciliumv2.ServiceListener{
  2475  			{
  2476  				Name:      "cilium-gateway-same-namespace",
  2477  				Namespace: "gateway-conformance-infra",
  2478  				Ports: []uint16{
  2479  					80,
  2480  				},
  2481  			},
  2482  		},
  2483  		BackendServices: []*ciliumv2.Service{
  2484  			{
  2485  				Name:      "infra-backend-v1",
  2486  				Namespace: "gateway-conformance-infra",
  2487  				Ports:     []string{"8080"},
  2488  			},
  2489  			{
  2490  				Name:      "infra-backend-v2",
  2491  				Namespace: "gateway-conformance-infra",
  2492  				Ports:     []string{"8080"},
  2493  			},
  2494  		},
  2495  		Resources: []ciliumv2.XDSResource{
  2496  			{Any: httpInsecureListenerXDSResource},
  2497  			{
  2498  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  2499  					Name: "listener-insecure",
  2500  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  2501  						{
  2502  							Name:    "*",
  2503  							Domains: []string{"*"},
  2504  							Routes: []*envoy_config_route_v3.Route{
  2505  								{
  2506  									Match: &envoy_config_route_v3.RouteMatch{
  2507  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  2508  											Prefix: "/",
  2509  										},
  2510  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  2511  											{
  2512  												Name: ":method",
  2513  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  2514  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2515  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2516  															Exact: "GET",
  2517  														},
  2518  													},
  2519  												},
  2520  											},
  2521  										},
  2522  									},
  2523  									Action: routeActionBackendV2,
  2524  								},
  2525  								{
  2526  									Match: &envoy_config_route_v3.RouteMatch{
  2527  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  2528  											Prefix: "/",
  2529  										},
  2530  										Headers: []*envoy_config_route_v3.HeaderMatcher{
  2531  											{
  2532  												Name: ":method",
  2533  												HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{
  2534  													StringMatch: &envoy_type_matcher_v3.StringMatcher{
  2535  														MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
  2536  															Exact: "POST",
  2537  														},
  2538  													},
  2539  												},
  2540  											},
  2541  										},
  2542  									},
  2543  									Action: routeActionBackendV1,
  2544  								},
  2545  							},
  2546  						},
  2547  					},
  2548  				}),
  2549  			},
  2550  			{Any: backendV1XDSResource},
  2551  			{Any: backendV2XDSResource},
  2552  		},
  2553  	},
  2554  }
  2555  
  2556  // requestHeaderModifierHTTPListeners is the internal model for Conformance/HTTPRouteRequestHeaderModifier
  2557  var requestHeaderModifierHTTPListeners = []model.HTTPListener{
  2558  	{
  2559  		Name: "http",
  2560  		Sources: []model.FullyQualifiedResource{
  2561  			{
  2562  				Name:      "same-namespace",
  2563  				Namespace: "gateway-conformance-infra",
  2564  				Group:     "gateway.networking.k8s.io",
  2565  				Version:   "v1",
  2566  				Kind:      "Gateway",
  2567  			},
  2568  		},
  2569  		Port: 80, Hostname: "*",
  2570  		Routes: []model.HTTPRoute{
  2571  			{
  2572  				PathMatch: model.StringMatch{Exact: "/set"},
  2573  				Backends: []model.Backend{
  2574  					{
  2575  						Name:      "infra-backend-v1",
  2576  						Namespace: "gateway-conformance-infra",
  2577  						Port: &model.BackendPort{
  2578  							Port: 8080,
  2579  						},
  2580  					},
  2581  				},
  2582  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  2583  					HeadersToSet: []model.Header{
  2584  						{
  2585  							Name:  "X-Header-Set",
  2586  							Value: "set-overwrites-values",
  2587  						},
  2588  					},
  2589  				},
  2590  			},
  2591  			{
  2592  				PathMatch: model.StringMatch{Exact: "/add"},
  2593  				Backends: []model.Backend{
  2594  					{
  2595  						Name:      "infra-backend-v1",
  2596  						Namespace: "gateway-conformance-infra",
  2597  						Port: &model.BackendPort{
  2598  							Port: 8080,
  2599  						},
  2600  					},
  2601  				},
  2602  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  2603  					HeadersToAdd: []model.Header{
  2604  						{
  2605  							Name:  "X-Header-Add",
  2606  							Value: "add-appends-values",
  2607  						},
  2608  					},
  2609  				},
  2610  			},
  2611  			{
  2612  				PathMatch: model.StringMatch{Exact: "/remove"},
  2613  				Backends: []model.Backend{
  2614  					{
  2615  						Name:      "infra-backend-v1",
  2616  						Namespace: "gateway-conformance-infra",
  2617  						Port: &model.BackendPort{
  2618  							Port: 8080,
  2619  						},
  2620  					},
  2621  				},
  2622  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  2623  					HeadersToRemove: []string{"X-Header-Remove"},
  2624  				},
  2625  			},
  2626  			{
  2627  				PathMatch: model.StringMatch{Exact: "/multiple"},
  2628  				Backends: []model.Backend{
  2629  					{
  2630  						Name:      "infra-backend-v1",
  2631  						Namespace: "gateway-conformance-infra",
  2632  						Port: &model.BackendPort{
  2633  							Port: 8080,
  2634  						},
  2635  					},
  2636  				},
  2637  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  2638  					HeadersToAdd: []model.Header{
  2639  						{
  2640  							Name:  "X-Header-Add-1",
  2641  							Value: "header-add-1",
  2642  						},
  2643  						{
  2644  							Name:  "X-Header-Add-2",
  2645  							Value: "header-add-2",
  2646  						},
  2647  						{
  2648  							Name:  "X-Header-Add-3",
  2649  							Value: "header-add-3",
  2650  						},
  2651  					},
  2652  					HeadersToSet: []model.Header{
  2653  						{
  2654  							Name:  "X-Header-Set-1",
  2655  							Value: "header-set-1",
  2656  						},
  2657  						{
  2658  							Name:  "X-Header-Set-2",
  2659  							Value: "header-set-2",
  2660  						},
  2661  					},
  2662  					HeadersToRemove: []string{
  2663  						"X-Header-Remove-1",
  2664  						"X-Header-Remove-2",
  2665  					},
  2666  				},
  2667  			},
  2668  			{
  2669  				PathMatch: model.StringMatch{Exact: "/case-insensitivity"},
  2670  				Backends: []model.Backend{
  2671  					{
  2672  						Name:      "infra-backend-v1",
  2673  						Namespace: "gateway-conformance-infra",
  2674  						Port: &model.BackendPort{
  2675  							Port: 8080,
  2676  						},
  2677  					},
  2678  				},
  2679  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  2680  					HeadersToAdd: []model.Header{
  2681  						{
  2682  							Name:  "X-Header-Add",
  2683  							Value: "header-add",
  2684  						},
  2685  					},
  2686  					HeadersToSet: []model.Header{
  2687  						{
  2688  							Name:  "X-Header-Set",
  2689  							Value: "header-set",
  2690  						},
  2691  					},
  2692  					HeadersToRemove: []string{
  2693  						"X-Header-Remove",
  2694  					},
  2695  				},
  2696  			},
  2697  		},
  2698  	},
  2699  }
  2700  
  2701  var requestHeaderModifierHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  2702  	ObjectMeta: metav1.ObjectMeta{
  2703  		Name:      "cilium-gateway-same-namespace",
  2704  		Namespace: "gateway-conformance-infra",
  2705  		Labels: map[string]string{
  2706  			"cilium.io/use-original-source-address":  "false",
  2707  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  2708  		},
  2709  		OwnerReferences: []metav1.OwnerReference{
  2710  			{
  2711  				APIVersion: "gateway.networking.k8s.io/v1",
  2712  				Kind:       "Gateway",
  2713  				Name:       "same-namespace",
  2714  				Controller: model.AddressOf(true),
  2715  			},
  2716  		},
  2717  	},
  2718  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  2719  		Services: []*ciliumv2.ServiceListener{
  2720  			{
  2721  				Name:      "cilium-gateway-same-namespace",
  2722  				Namespace: "gateway-conformance-infra",
  2723  				Ports: []uint16{
  2724  					80,
  2725  				},
  2726  			},
  2727  		},
  2728  		BackendServices: []*ciliumv2.Service{
  2729  			{
  2730  				Name:      "infra-backend-v1",
  2731  				Namespace: "gateway-conformance-infra",
  2732  				Ports:     []string{"8080"},
  2733  			},
  2734  		},
  2735  		Resources: []ciliumv2.XDSResource{
  2736  			{Any: httpInsecureListenerXDSResource},
  2737  			{
  2738  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  2739  					Name: "listener-insecure",
  2740  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  2741  						{
  2742  							Name:    "*",
  2743  							Domains: []string{"*"},
  2744  							Routes: []*envoy_config_route_v3.Route{
  2745  								{
  2746  									Match: &envoy_config_route_v3.RouteMatch{
  2747  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  2748  											Path: "/case-insensitivity",
  2749  										},
  2750  									},
  2751  									RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  2752  										{
  2753  											Header: &envoy_config_core_v3.HeaderValue{
  2754  												Key:   "X-Header-Add",
  2755  												Value: "header-add",
  2756  											},
  2757  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  2758  										},
  2759  										{
  2760  											Header: &envoy_config_core_v3.HeaderValue{
  2761  												Key:   "X-Header-Set",
  2762  												Value: "header-set",
  2763  											},
  2764  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  2765  										},
  2766  									},
  2767  									RequestHeadersToRemove: []string{"X-Header-Remove"},
  2768  									Action:                 routeActionBackendV1,
  2769  								},
  2770  								{
  2771  									Match: &envoy_config_route_v3.RouteMatch{
  2772  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  2773  											Path: "/multiple",
  2774  										},
  2775  									},
  2776  									RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  2777  										{
  2778  											Header: &envoy_config_core_v3.HeaderValue{
  2779  												Key:   "X-Header-Add-1",
  2780  												Value: "header-add-1",
  2781  											},
  2782  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  2783  										},
  2784  										{
  2785  											Header: &envoy_config_core_v3.HeaderValue{
  2786  												Key:   "X-Header-Add-2",
  2787  												Value: "header-add-2",
  2788  											},
  2789  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  2790  										},
  2791  										{
  2792  											Header: &envoy_config_core_v3.HeaderValue{
  2793  												Key:   "X-Header-Add-3",
  2794  												Value: "header-add-3",
  2795  											},
  2796  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  2797  										},
  2798  										{
  2799  											Header: &envoy_config_core_v3.HeaderValue{
  2800  												Key:   "X-Header-Set-1",
  2801  												Value: "header-set-1",
  2802  											},
  2803  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  2804  										},
  2805  										{
  2806  											Header: &envoy_config_core_v3.HeaderValue{
  2807  												Key:   "X-Header-Set-2",
  2808  												Value: "header-set-2",
  2809  											},
  2810  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  2811  										},
  2812  									},
  2813  									RequestHeadersToRemove: []string{"X-Header-Remove-1", "X-Header-Remove-2"},
  2814  									Action:                 routeActionBackendV1,
  2815  								},
  2816  								{
  2817  									Match: &envoy_config_route_v3.RouteMatch{
  2818  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  2819  											Path: "/remove",
  2820  										},
  2821  									},
  2822  									RequestHeadersToRemove: []string{"X-Header-Remove"},
  2823  									Action:                 routeActionBackendV1,
  2824  								},
  2825  								{
  2826  									Match: &envoy_config_route_v3.RouteMatch{
  2827  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  2828  											Path: "/set",
  2829  										},
  2830  									},
  2831  									RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  2832  										{
  2833  											Header: &envoy_config_core_v3.HeaderValue{
  2834  												Key:   "X-Header-Set",
  2835  												Value: "set-overwrites-values",
  2836  											},
  2837  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  2838  										},
  2839  									},
  2840  									Action: routeActionBackendV1,
  2841  								},
  2842  								{
  2843  									Match: &envoy_config_route_v3.RouteMatch{
  2844  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  2845  											Path: "/add",
  2846  										},
  2847  									},
  2848  									RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  2849  										{
  2850  											Header: &envoy_config_core_v3.HeaderValue{
  2851  												Key:   "X-Header-Add",
  2852  												Value: "add-appends-values",
  2853  											},
  2854  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  2855  										},
  2856  									},
  2857  									Action: routeActionBackendV1,
  2858  								},
  2859  							},
  2860  						},
  2861  					},
  2862  				}),
  2863  			},
  2864  			{Any: backendV1XDSResource},
  2865  		},
  2866  	},
  2867  }
  2868  
  2869  // backendRefsRequestHeaderModifierHTTPListeners is the internal model for Conformance/HTTPRouteBackendRefsRequestHeaderModifier
  2870  var backendRefsRequestHeaderModifierHTTPListeners = []model.HTTPListener{
  2871  	{
  2872  		Name: "http",
  2873  		Sources: []model.FullyQualifiedResource{
  2874  			{
  2875  				Name:      "same-namespace",
  2876  				Namespace: "gateway-conformance-infra",
  2877  				Group:     "gateway.networking.k8s.io",
  2878  				Version:   "v1",
  2879  				Kind:      "Gateway",
  2880  			},
  2881  		},
  2882  		Port: 80, Hostname: "*",
  2883  		Routes: []model.HTTPRoute{
  2884  			{
  2885  				PathMatch: model.StringMatch{Exact: "/set"},
  2886  				Backends: []model.Backend{
  2887  					{
  2888  						Name:      "infra-backend-v1",
  2889  						Namespace: "gateway-conformance-infra",
  2890  						Port: &model.BackendPort{
  2891  							Port: 8080,
  2892  						},
  2893  					},
  2894  				},
  2895  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  2896  					{
  2897  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  2898  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  2899  							HeadersToSet: []model.Header{
  2900  								{
  2901  									Name:  "X-Header-Set",
  2902  									Value: "set-overwrites-values",
  2903  								},
  2904  							},
  2905  						},
  2906  					},
  2907  				},
  2908  			},
  2909  			{
  2910  				PathMatch: model.StringMatch{Exact: "/add"},
  2911  				Backends: []model.Backend{
  2912  					{
  2913  						Name:      "infra-backend-v1",
  2914  						Namespace: "gateway-conformance-infra",
  2915  						Port: &model.BackendPort{
  2916  							Port: 8080,
  2917  						},
  2918  					},
  2919  				},
  2920  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  2921  					{
  2922  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  2923  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  2924  							HeadersToAdd: []model.Header{
  2925  								{
  2926  									Name:  "X-Header-Add",
  2927  									Value: "add-appends-values",
  2928  								},
  2929  							},
  2930  						},
  2931  					},
  2932  				},
  2933  			},
  2934  			{
  2935  				PathMatch: model.StringMatch{Exact: "/remove"},
  2936  				Backends: []model.Backend{
  2937  					{
  2938  						Name:      "infra-backend-v1",
  2939  						Namespace: "gateway-conformance-infra",
  2940  						Port: &model.BackendPort{
  2941  							Port: 8080,
  2942  						},
  2943  					},
  2944  				},
  2945  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  2946  					{
  2947  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  2948  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  2949  							HeadersToRemove: []string{"X-Header-Remove"},
  2950  						},
  2951  					},
  2952  				},
  2953  			},
  2954  			{
  2955  				PathMatch: model.StringMatch{Exact: "/multiple"},
  2956  				Backends: []model.Backend{
  2957  					{
  2958  						Name:      "infra-backend-v1",
  2959  						Namespace: "gateway-conformance-infra",
  2960  						Port: &model.BackendPort{
  2961  							Port: 8080,
  2962  						},
  2963  					},
  2964  				},
  2965  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  2966  					{
  2967  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  2968  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  2969  							HeadersToAdd: []model.Header{
  2970  								{
  2971  									Name:  "X-Header-Add-1",
  2972  									Value: "header-add-1",
  2973  								},
  2974  								{
  2975  									Name:  "X-Header-Add-2",
  2976  									Value: "header-add-2",
  2977  								},
  2978  								{
  2979  									Name:  "X-Header-Add-3",
  2980  									Value: "header-add-3",
  2981  								},
  2982  							},
  2983  							HeadersToSet: []model.Header{
  2984  								{
  2985  									Name:  "X-Header-Set-1",
  2986  									Value: "header-set-1",
  2987  								},
  2988  								{
  2989  									Name:  "X-Header-Set-2",
  2990  									Value: "header-set-2",
  2991  								},
  2992  							},
  2993  							HeadersToRemove: []string{
  2994  								"X-Header-Remove-1",
  2995  								"X-Header-Remove-2",
  2996  							},
  2997  						},
  2998  					},
  2999  				},
  3000  			},
  3001  			{
  3002  				PathMatch: model.StringMatch{Exact: "/multiple-backends"},
  3003  				Backends: []model.Backend{
  3004  					{
  3005  						Name:      "infra-backend-v1",
  3006  						Namespace: "gateway-conformance-infra",
  3007  						Port: &model.BackendPort{
  3008  							Port: 8080,
  3009  						},
  3010  						Weight: ptr.To[int32](50),
  3011  					},
  3012  					{
  3013  						Name:      "infra-backend-v2",
  3014  						Namespace: "gateway-conformance-infra",
  3015  						Port: &model.BackendPort{
  3016  							Port: 8080,
  3017  						},
  3018  						Weight: ptr.To[int32](50),
  3019  					},
  3020  				},
  3021  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3022  					{
  3023  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  3024  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  3025  							HeadersToAdd: []model.Header{
  3026  								{
  3027  									Name:  "X-Header-Add-1",
  3028  									Value: "header-add-1",
  3029  								},
  3030  								{
  3031  									Name:  "X-Header-Add-1-2",
  3032  									Value: "header-add-1-2",
  3033  								},
  3034  							},
  3035  							HeadersToSet: []model.Header{
  3036  								{
  3037  									Name:  "X-Header-Set-1",
  3038  									Value: "header-set-1",
  3039  								},
  3040  								{
  3041  									Name:  "X-Header-Set-1-2",
  3042  									Value: "header-set-1-2",
  3043  								},
  3044  							},
  3045  							HeadersToRemove: []string{
  3046  								"X-Header-Remove-1-1",
  3047  								"X-Header-Remove-1-2",
  3048  							},
  3049  						},
  3050  					},
  3051  					{
  3052  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  3053  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  3054  							HeadersToAdd: []model.Header{
  3055  								{
  3056  									Name:  "X-Header-Add-2",
  3057  									Value: "header-add-2",
  3058  								},
  3059  							},
  3060  							HeadersToSet: []model.Header{
  3061  								{
  3062  									Name:  "X-Header-Set-2",
  3063  									Value: "header-set-2",
  3064  								},
  3065  							},
  3066  							HeadersToRemove: []string{
  3067  								"X-Header-Remove-2",
  3068  							},
  3069  						},
  3070  					},
  3071  				},
  3072  			},
  3073  			{
  3074  				PathMatch: model.StringMatch{Exact: "/multiple-backends-some-missing"},
  3075  				Backends: []model.Backend{
  3076  					{
  3077  						Name:      "infra-backend-v1",
  3078  						Namespace: "gateway-conformance-infra",
  3079  						Port: &model.BackendPort{
  3080  							Port: 8080,
  3081  						},
  3082  						Weight: ptr.To[int32](50),
  3083  					},
  3084  					{
  3085  						Name:      "infra-backend-v2",
  3086  						Namespace: "gateway-conformance-infra",
  3087  						Port: &model.BackendPort{
  3088  							Port: 8080,
  3089  						},
  3090  						Weight: ptr.To[int32](50),
  3091  					},
  3092  				},
  3093  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3094  					{
  3095  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  3096  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  3097  							HeadersToAdd: []model.Header{
  3098  								{
  3099  									Name:  "X-Header-Add-2",
  3100  									Value: "header-add-2",
  3101  								},
  3102  							},
  3103  							HeadersToSet: []model.Header{
  3104  								{
  3105  									Name:  "X-Header-Set-2",
  3106  									Value: "header-set-2",
  3107  								},
  3108  							},
  3109  							HeadersToRemove: []string{
  3110  								"X-Header-Remove-2",
  3111  							},
  3112  						},
  3113  					},
  3114  				},
  3115  			},
  3116  			{
  3117  				PathMatch: model.StringMatch{Exact: "/multiple-backends-two-filters"},
  3118  				Backends: []model.Backend{
  3119  					{
  3120  						Name:      "infra-backend-v1",
  3121  						Namespace: "gateway-conformance-infra",
  3122  						Port: &model.BackendPort{
  3123  							Port: 8080,
  3124  						},
  3125  						Weight: ptr.To[int32](10),
  3126  					},
  3127  					{
  3128  						Name:      "infra-backend-v2",
  3129  						Namespace: "gateway-conformance-infra",
  3130  						Port: &model.BackendPort{
  3131  							Port: 8080,
  3132  						},
  3133  						Weight: ptr.To[int32](20),
  3134  					},
  3135  					{
  3136  						Name:      "infra-backend-v3",
  3137  						Namespace: "gateway-conformance-infra",
  3138  						Port: &model.BackendPort{
  3139  							Port: 8080,
  3140  						},
  3141  						Weight: ptr.To[int32](70),
  3142  					},
  3143  				},
  3144  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3145  					{
  3146  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  3147  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  3148  							HeadersToAdd: []model.Header{
  3149  								{
  3150  									Name:  "X-Header-Add-2",
  3151  									Value: "header-add-2",
  3152  								},
  3153  							},
  3154  							HeadersToSet: []model.Header{
  3155  								{
  3156  									Name:  "X-Header-Set-2",
  3157  									Value: "header-set-2",
  3158  								},
  3159  							},
  3160  							HeadersToRemove: []string{
  3161  								"X-Header-Remove-2",
  3162  							},
  3163  						},
  3164  					},
  3165  					{
  3166  						Name: "gateway-conformance-infra:infra-backend-v3:8080",
  3167  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  3168  							HeadersToAdd: []model.Header{
  3169  								{
  3170  									Name:  "X-Header-Add-3",
  3171  									Value: "header-add-3",
  3172  								},
  3173  							},
  3174  							HeadersToSet: []model.Header{
  3175  								{
  3176  									Name:  "X-Header-Set-3",
  3177  									Value: "header-set-3",
  3178  								},
  3179  							},
  3180  							HeadersToRemove: []string{
  3181  								"X-Header-Remove-3",
  3182  							},
  3183  						},
  3184  					},
  3185  				},
  3186  			},
  3187  		},
  3188  	},
  3189  }
  3190  
  3191  var backendRefsRequestHeaderModifierHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  3192  	ObjectMeta: metav1.ObjectMeta{
  3193  		Name:      "cilium-gateway-same-namespace",
  3194  		Namespace: "gateway-conformance-infra",
  3195  		Labels: map[string]string{
  3196  			"cilium.io/use-original-source-address":  "false",
  3197  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  3198  		},
  3199  		OwnerReferences: []metav1.OwnerReference{
  3200  			{
  3201  				APIVersion: "gateway.networking.k8s.io/v1",
  3202  				Kind:       "Gateway",
  3203  				Name:       "same-namespace",
  3204  				Controller: model.AddressOf(true),
  3205  			},
  3206  		},
  3207  	},
  3208  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  3209  		Services: []*ciliumv2.ServiceListener{
  3210  			{
  3211  				Name:      "cilium-gateway-same-namespace",
  3212  				Namespace: "gateway-conformance-infra",
  3213  				Ports: []uint16{
  3214  					80,
  3215  				},
  3216  			},
  3217  		},
  3218  		BackendServices: []*ciliumv2.Service{
  3219  			{
  3220  				Name:      "infra-backend-v1",
  3221  				Namespace: "gateway-conformance-infra",
  3222  				Ports:     []string{"8080"},
  3223  			},
  3224  			{
  3225  				Name:      "infra-backend-v2",
  3226  				Namespace: "gateway-conformance-infra",
  3227  				Ports:     []string{"8080"},
  3228  			},
  3229  			{
  3230  				Name:      "infra-backend-v3",
  3231  				Namespace: "gateway-conformance-infra",
  3232  				Ports:     []string{"8080"},
  3233  			},
  3234  		},
  3235  		Resources: []ciliumv2.XDSResource{
  3236  			{Any: httpInsecureListenerXDSResource},
  3237  			{Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  3238  				Name: "listener-insecure",
  3239  				VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  3240  					{
  3241  						Name:    "*",
  3242  						Domains: []string{"*"},
  3243  						Routes: []*envoy_config_route_v3.Route{
  3244  							{
  3245  								Match: &envoy_config_route_v3.RouteMatch{
  3246  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3247  										Path: "/multiple-backends-some-missing",
  3248  									},
  3249  								},
  3250  								Action: &envoy_config_route_v3.Route_Route{
  3251  									Route: &envoy_config_route_v3.RouteAction{
  3252  										ClusterSpecifier: &envoy_config_route_v3.RouteAction_WeightedClusters{
  3253  											WeightedClusters: &envoy_config_route_v3.WeightedCluster{
  3254  												Clusters: []*envoy_config_route_v3.WeightedCluster_ClusterWeight{
  3255  													{
  3256  														Name:   "gateway-conformance-infra:infra-backend-v1:8080",
  3257  														Weight: wrapperspb.UInt32(uint32(50)),
  3258  													},
  3259  													{
  3260  														Name:   "gateway-conformance-infra:infra-backend-v2:8080",
  3261  														Weight: wrapperspb.UInt32(uint32(50)),
  3262  														RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3263  															{
  3264  																Header: &envoy_config_core_v3.HeaderValue{
  3265  																	Key:   "X-Header-Add-2",
  3266  																	Value: "header-add-2",
  3267  																},
  3268  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3269  															},
  3270  															{
  3271  																Header: &envoy_config_core_v3.HeaderValue{
  3272  																	Key:   "X-Header-Set-2",
  3273  																	Value: "header-set-2",
  3274  																},
  3275  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3276  															},
  3277  														},
  3278  														RequestHeadersToRemove: []string{"X-Header-Remove-2"},
  3279  													},
  3280  												},
  3281  											},
  3282  										},
  3283  										MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  3284  											MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  3285  										},
  3286  									},
  3287  								},
  3288  							},
  3289  							{
  3290  								Match: &envoy_config_route_v3.RouteMatch{
  3291  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3292  										Path: "/multiple-backends-two-filters",
  3293  									},
  3294  								},
  3295  								Action: &envoy_config_route_v3.Route_Route{
  3296  									Route: &envoy_config_route_v3.RouteAction{
  3297  										ClusterSpecifier: &envoy_config_route_v3.RouteAction_WeightedClusters{
  3298  											WeightedClusters: &envoy_config_route_v3.WeightedCluster{
  3299  												Clusters: []*envoy_config_route_v3.WeightedCluster_ClusterWeight{
  3300  													{
  3301  														Name:   "gateway-conformance-infra:infra-backend-v1:8080",
  3302  														Weight: wrapperspb.UInt32(uint32(10)),
  3303  													},
  3304  													{
  3305  														Name:   "gateway-conformance-infra:infra-backend-v2:8080",
  3306  														Weight: wrapperspb.UInt32(uint32(20)),
  3307  														RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3308  															{
  3309  																Header: &envoy_config_core_v3.HeaderValue{
  3310  																	Key:   "X-Header-Add-2",
  3311  																	Value: "header-add-2",
  3312  																},
  3313  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3314  															},
  3315  															{
  3316  																Header: &envoy_config_core_v3.HeaderValue{
  3317  																	Key:   "X-Header-Set-2",
  3318  																	Value: "header-set-2",
  3319  																},
  3320  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3321  															},
  3322  														},
  3323  														RequestHeadersToRemove: []string{"X-Header-Remove-2"},
  3324  													},
  3325  													{
  3326  														Name:   "gateway-conformance-infra:infra-backend-v3:8080",
  3327  														Weight: wrapperspb.UInt32(uint32(70)),
  3328  														RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3329  															{
  3330  																Header: &envoy_config_core_v3.HeaderValue{
  3331  																	Key:   "X-Header-Add-3",
  3332  																	Value: "header-add-3",
  3333  																},
  3334  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3335  															},
  3336  															{
  3337  																Header: &envoy_config_core_v3.HeaderValue{
  3338  																	Key:   "X-Header-Set-3",
  3339  																	Value: "header-set-3",
  3340  																},
  3341  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3342  															},
  3343  														},
  3344  														RequestHeadersToRemove: []string{"X-Header-Remove-3"},
  3345  													},
  3346  												},
  3347  											},
  3348  										},
  3349  										MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  3350  											MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  3351  										},
  3352  									},
  3353  								},
  3354  							},
  3355  							{
  3356  								Match: &envoy_config_route_v3.RouteMatch{
  3357  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3358  										Path: "/multiple-backends",
  3359  									},
  3360  								},
  3361  								Action: &envoy_config_route_v3.Route_Route{
  3362  									Route: &envoy_config_route_v3.RouteAction{
  3363  										ClusterSpecifier: &envoy_config_route_v3.RouteAction_WeightedClusters{
  3364  											WeightedClusters: &envoy_config_route_v3.WeightedCluster{
  3365  												Clusters: []*envoy_config_route_v3.WeightedCluster_ClusterWeight{
  3366  													{
  3367  														Name:   "gateway-conformance-infra:infra-backend-v1:8080",
  3368  														Weight: wrapperspb.UInt32(uint32(50)),
  3369  														RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3370  															{
  3371  																Header: &envoy_config_core_v3.HeaderValue{
  3372  																	Key:   "X-Header-Add-1",
  3373  																	Value: "header-add-1",
  3374  																},
  3375  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3376  															},
  3377  															{
  3378  																Header: &envoy_config_core_v3.HeaderValue{
  3379  																	Key:   "X-Header-Add-1-2",
  3380  																	Value: "header-add-1-2",
  3381  																},
  3382  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3383  															},
  3384  															{
  3385  																Header: &envoy_config_core_v3.HeaderValue{
  3386  																	Key:   "X-Header-Set-1",
  3387  																	Value: "header-set-1",
  3388  																},
  3389  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3390  															},
  3391  															{
  3392  																Header: &envoy_config_core_v3.HeaderValue{
  3393  																	Key:   "X-Header-Set-1-2",
  3394  																	Value: "header-set-1-2",
  3395  																},
  3396  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3397  															},
  3398  														},
  3399  														RequestHeadersToRemove: []string{"X-Header-Remove-1-1", "X-Header-Remove-1-2"},
  3400  													},
  3401  													{
  3402  														Name:   "gateway-conformance-infra:infra-backend-v2:8080",
  3403  														Weight: wrapperspb.UInt32(uint32(50)),
  3404  														RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3405  															{
  3406  																Header: &envoy_config_core_v3.HeaderValue{
  3407  																	Key:   "X-Header-Add-2",
  3408  																	Value: "header-add-2",
  3409  																},
  3410  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3411  															},
  3412  															{
  3413  																Header: &envoy_config_core_v3.HeaderValue{
  3414  																	Key:   "X-Header-Set-2",
  3415  																	Value: "header-set-2",
  3416  																},
  3417  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3418  															},
  3419  														},
  3420  														RequestHeadersToRemove: []string{"X-Header-Remove-2"},
  3421  													},
  3422  												},
  3423  											},
  3424  										},
  3425  										MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  3426  											MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  3427  										},
  3428  									},
  3429  								},
  3430  							},
  3431  							{
  3432  								Match: &envoy_config_route_v3.RouteMatch{
  3433  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3434  										Path: "/multiple",
  3435  									},
  3436  								},
  3437  								RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3438  									{
  3439  										Header: &envoy_config_core_v3.HeaderValue{
  3440  											Key:   "X-Header-Add-1",
  3441  											Value: "header-add-1",
  3442  										},
  3443  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3444  									},
  3445  									{
  3446  										Header: &envoy_config_core_v3.HeaderValue{
  3447  											Key:   "X-Header-Add-2",
  3448  											Value: "header-add-2",
  3449  										},
  3450  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3451  									},
  3452  									{
  3453  										Header: &envoy_config_core_v3.HeaderValue{
  3454  											Key:   "X-Header-Add-3",
  3455  											Value: "header-add-3",
  3456  										},
  3457  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3458  									},
  3459  									{
  3460  										Header: &envoy_config_core_v3.HeaderValue{
  3461  											Key:   "X-Header-Set-1",
  3462  											Value: "header-set-1",
  3463  										},
  3464  										AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3465  									},
  3466  									{
  3467  										Header: &envoy_config_core_v3.HeaderValue{
  3468  											Key:   "X-Header-Set-2",
  3469  											Value: "header-set-2",
  3470  										},
  3471  										AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3472  									},
  3473  								},
  3474  								RequestHeadersToRemove: []string{"X-Header-Remove-1", "X-Header-Remove-2"},
  3475  								Action:                 routeActionBackendV1,
  3476  							},
  3477  							{
  3478  								Match: &envoy_config_route_v3.RouteMatch{
  3479  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3480  										Path: "/remove",
  3481  									},
  3482  								},
  3483  								RequestHeadersToRemove: []string{"X-Header-Remove"},
  3484  								Action:                 routeActionBackendV1,
  3485  							},
  3486  							{
  3487  								Match: &envoy_config_route_v3.RouteMatch{
  3488  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3489  										Path: "/set",
  3490  									},
  3491  								},
  3492  								RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3493  									{
  3494  										Header: &envoy_config_core_v3.HeaderValue{
  3495  											Key:   "X-Header-Set",
  3496  											Value: "set-overwrites-values",
  3497  										},
  3498  										AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3499  									},
  3500  								},
  3501  								Action: routeActionBackendV1,
  3502  							},
  3503  							{
  3504  								Match: &envoy_config_route_v3.RouteMatch{
  3505  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3506  										Path: "/add",
  3507  									},
  3508  								},
  3509  								RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3510  									{
  3511  										Header: &envoy_config_core_v3.HeaderValue{
  3512  											Key:   "X-Header-Add",
  3513  											Value: "add-appends-values",
  3514  										},
  3515  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3516  									},
  3517  								},
  3518  								Action: routeActionBackendV1,
  3519  							},
  3520  						},
  3521  					},
  3522  				},
  3523  			})},
  3524  			{Any: backendV1XDSResource},
  3525  			{Any: backendV2XDSResource},
  3526  			{Any: backendV3XDSResource},
  3527  		},
  3528  	},
  3529  }
  3530  
  3531  // backendRefsResponseHeaderModifierHTTPListeners is the internal model for Conformance/HTTPRouteBackendRefsResponseHeaderModifier
  3532  var backendRefsResponseHeaderModifierHTTPListeners = []model.HTTPListener{
  3533  	{
  3534  		Name: "http",
  3535  		Sources: []model.FullyQualifiedResource{
  3536  			{
  3537  				Name:      "same-namespace",
  3538  				Namespace: "gateway-conformance-infra",
  3539  				Group:     "gateway.networking.k8s.io",
  3540  				Version:   "v1",
  3541  				Kind:      "Gateway",
  3542  			},
  3543  		},
  3544  		Port: 80, Hostname: "*",
  3545  		Routes: []model.HTTPRoute{
  3546  			{
  3547  				PathMatch: model.StringMatch{Exact: "/set"},
  3548  				Backends: []model.Backend{
  3549  					{
  3550  						Name:      "infra-backend-v1",
  3551  						Namespace: "gateway-conformance-infra",
  3552  						Port: &model.BackendPort{
  3553  							Port: 8080,
  3554  						},
  3555  					},
  3556  				},
  3557  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3558  					{
  3559  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  3560  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3561  							HeadersToSet: []model.Header{
  3562  								{
  3563  									Name:  "X-Header-Set",
  3564  									Value: "set-overwrites-values",
  3565  								},
  3566  							},
  3567  						},
  3568  					},
  3569  				},
  3570  			},
  3571  			{
  3572  				PathMatch: model.StringMatch{Exact: "/add"},
  3573  				Backends: []model.Backend{
  3574  					{
  3575  						Name:      "infra-backend-v1",
  3576  						Namespace: "gateway-conformance-infra",
  3577  						Port: &model.BackendPort{
  3578  							Port: 8080,
  3579  						},
  3580  					},
  3581  				},
  3582  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3583  					{
  3584  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  3585  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3586  							HeadersToAdd: []model.Header{
  3587  								{
  3588  									Name:  "X-Header-Add",
  3589  									Value: "add-appends-values",
  3590  								},
  3591  							},
  3592  						},
  3593  					},
  3594  				},
  3595  			},
  3596  			{
  3597  				PathMatch: model.StringMatch{Exact: "/remove"},
  3598  				Backends: []model.Backend{
  3599  					{
  3600  						Name:      "infra-backend-v1",
  3601  						Namespace: "gateway-conformance-infra",
  3602  						Port: &model.BackendPort{
  3603  							Port: 8080,
  3604  						},
  3605  					},
  3606  				},
  3607  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3608  					{
  3609  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  3610  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3611  							HeadersToRemove: []string{"X-Header-Remove"},
  3612  						},
  3613  					},
  3614  				},
  3615  			},
  3616  			{
  3617  				PathMatch: model.StringMatch{Exact: "/multiple"},
  3618  				Backends: []model.Backend{
  3619  					{
  3620  						Name:      "infra-backend-v1",
  3621  						Namespace: "gateway-conformance-infra",
  3622  						Port: &model.BackendPort{
  3623  							Port: 8080,
  3624  						},
  3625  					},
  3626  				},
  3627  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3628  					{
  3629  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  3630  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3631  							HeadersToAdd: []model.Header{
  3632  								{
  3633  									Name:  "X-Header-Add-1",
  3634  									Value: "header-add-1",
  3635  								},
  3636  								{
  3637  									Name:  "X-Header-Add-2",
  3638  									Value: "header-add-2",
  3639  								},
  3640  								{
  3641  									Name:  "X-Header-Add-3",
  3642  									Value: "header-add-3",
  3643  								},
  3644  							},
  3645  							HeadersToSet: []model.Header{
  3646  								{
  3647  									Name:  "X-Header-Set-1",
  3648  									Value: "header-set-1",
  3649  								},
  3650  								{
  3651  									Name:  "X-Header-Set-2",
  3652  									Value: "header-set-2",
  3653  								},
  3654  							},
  3655  							HeadersToRemove: []string{
  3656  								"X-Header-Remove-1",
  3657  								"X-Header-Remove-2",
  3658  							},
  3659  						},
  3660  					},
  3661  				},
  3662  			},
  3663  			{
  3664  				PathMatch: model.StringMatch{Exact: "/multiple-backends"},
  3665  				Backends: []model.Backend{
  3666  					{
  3667  						Name:      "infra-backend-v1",
  3668  						Namespace: "gateway-conformance-infra",
  3669  						Port: &model.BackendPort{
  3670  							Port: 8080,
  3671  						},
  3672  						Weight: ptr.To[int32](50),
  3673  					},
  3674  					{
  3675  						Name:      "infra-backend-v2",
  3676  						Namespace: "gateway-conformance-infra",
  3677  						Port: &model.BackendPort{
  3678  							Port: 8080,
  3679  						},
  3680  						Weight: ptr.To[int32](50),
  3681  					},
  3682  				},
  3683  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3684  					{
  3685  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  3686  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3687  							HeadersToAdd: []model.Header{
  3688  								{
  3689  									Name:  "X-Header-Add-1",
  3690  									Value: "header-add-1",
  3691  								},
  3692  								{
  3693  									Name:  "X-Header-Add-1-2",
  3694  									Value: "header-add-1-2",
  3695  								},
  3696  							},
  3697  							HeadersToSet: []model.Header{
  3698  								{
  3699  									Name:  "X-Header-Set-1",
  3700  									Value: "header-set-1",
  3701  								},
  3702  								{
  3703  									Name:  "X-Header-Set-1-2",
  3704  									Value: "header-set-1-2",
  3705  								},
  3706  							},
  3707  							HeadersToRemove: []string{
  3708  								"X-Header-Remove-1-1",
  3709  								"X-Header-Remove-1-2",
  3710  							},
  3711  						},
  3712  					},
  3713  					{
  3714  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  3715  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3716  							HeadersToAdd: []model.Header{
  3717  								{
  3718  									Name:  "X-Header-Add-2",
  3719  									Value: "header-add-2",
  3720  								},
  3721  							},
  3722  							HeadersToSet: []model.Header{
  3723  								{
  3724  									Name:  "X-Header-Set-2",
  3725  									Value: "header-set-2",
  3726  								},
  3727  							},
  3728  							HeadersToRemove: []string{
  3729  								"X-Header-Remove-2",
  3730  							},
  3731  						},
  3732  					},
  3733  				},
  3734  			},
  3735  			{
  3736  				PathMatch: model.StringMatch{Exact: "/multiple-backends-some-missing"},
  3737  				Backends: []model.Backend{
  3738  					{
  3739  						Name:      "infra-backend-v1",
  3740  						Namespace: "gateway-conformance-infra",
  3741  						Port: &model.BackendPort{
  3742  							Port: 8080,
  3743  						},
  3744  						Weight: ptr.To[int32](50),
  3745  					},
  3746  					{
  3747  						Name:      "infra-backend-v2",
  3748  						Namespace: "gateway-conformance-infra",
  3749  						Port: &model.BackendPort{
  3750  							Port: 8080,
  3751  						},
  3752  						Weight: ptr.To[int32](50),
  3753  					},
  3754  				},
  3755  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3756  					{
  3757  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  3758  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3759  							HeadersToAdd: []model.Header{
  3760  								{
  3761  									Name:  "X-Header-Add-2",
  3762  									Value: "header-add-2",
  3763  								},
  3764  							},
  3765  							HeadersToSet: []model.Header{
  3766  								{
  3767  									Name:  "X-Header-Set-2",
  3768  									Value: "header-set-2",
  3769  								},
  3770  							},
  3771  							HeadersToRemove: []string{
  3772  								"X-Header-Remove-2",
  3773  							},
  3774  						},
  3775  					},
  3776  				},
  3777  			},
  3778  			{
  3779  				PathMatch: model.StringMatch{Exact: "/multiple-backends-two-filters"},
  3780  				Backends: []model.Backend{
  3781  					{
  3782  						Name:      "infra-backend-v1",
  3783  						Namespace: "gateway-conformance-infra",
  3784  						Port: &model.BackendPort{
  3785  							Port: 8080,
  3786  						},
  3787  						Weight: ptr.To[int32](10),
  3788  					},
  3789  					{
  3790  						Name:      "infra-backend-v2",
  3791  						Namespace: "gateway-conformance-infra",
  3792  						Port: &model.BackendPort{
  3793  							Port: 8080,
  3794  						},
  3795  						Weight: ptr.To[int32](20),
  3796  					},
  3797  					{
  3798  						Name:      "infra-backend-v3",
  3799  						Namespace: "gateway-conformance-infra",
  3800  						Port: &model.BackendPort{
  3801  							Port: 8080,
  3802  						},
  3803  						Weight: ptr.To[int32](70),
  3804  					},
  3805  				},
  3806  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  3807  					{
  3808  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  3809  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3810  							HeadersToAdd: []model.Header{
  3811  								{
  3812  									Name:  "X-Header-Add-2",
  3813  									Value: "header-add-2",
  3814  								},
  3815  							},
  3816  							HeadersToSet: []model.Header{
  3817  								{
  3818  									Name:  "X-Header-Set-2",
  3819  									Value: "header-set-2",
  3820  								},
  3821  							},
  3822  							HeadersToRemove: []string{
  3823  								"X-Header-Remove-2",
  3824  							},
  3825  						},
  3826  					},
  3827  					{
  3828  						Name: "gateway-conformance-infra:infra-backend-v3:8080",
  3829  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  3830  							HeadersToAdd: []model.Header{
  3831  								{
  3832  									Name:  "X-Header-Add-3",
  3833  									Value: "header-add-3",
  3834  								},
  3835  							},
  3836  							HeadersToSet: []model.Header{
  3837  								{
  3838  									Name:  "X-Header-Set-3",
  3839  									Value: "header-set-3",
  3840  								},
  3841  							},
  3842  							HeadersToRemove: []string{
  3843  								"X-Header-Remove-3",
  3844  							},
  3845  						},
  3846  					},
  3847  				},
  3848  			},
  3849  		},
  3850  	},
  3851  }
  3852  
  3853  var backendRefsResponseHeaderModifierHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  3854  	ObjectMeta: metav1.ObjectMeta{
  3855  		Name:      "cilium-gateway-same-namespace",
  3856  		Namespace: "gateway-conformance-infra",
  3857  		Labels: map[string]string{
  3858  			"cilium.io/use-original-source-address":  "false",
  3859  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  3860  		},
  3861  		OwnerReferences: []metav1.OwnerReference{
  3862  			{
  3863  				APIVersion: "gateway.networking.k8s.io/v1",
  3864  				Kind:       "Gateway",
  3865  				Name:       "same-namespace",
  3866  				Controller: model.AddressOf(true),
  3867  			},
  3868  		},
  3869  	},
  3870  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  3871  		Services: []*ciliumv2.ServiceListener{
  3872  			{
  3873  				Name:      "cilium-gateway-same-namespace",
  3874  				Namespace: "gateway-conformance-infra",
  3875  				Ports: []uint16{
  3876  					80,
  3877  				},
  3878  			},
  3879  		},
  3880  		BackendServices: []*ciliumv2.Service{
  3881  			{
  3882  				Name:      "infra-backend-v1",
  3883  				Namespace: "gateway-conformance-infra",
  3884  				Ports:     []string{"8080"},
  3885  			},
  3886  			{
  3887  				Name:      "infra-backend-v2",
  3888  				Namespace: "gateway-conformance-infra",
  3889  				Ports:     []string{"8080"},
  3890  			},
  3891  			{
  3892  				Name:      "infra-backend-v3",
  3893  				Namespace: "gateway-conformance-infra",
  3894  				Ports:     []string{"8080"},
  3895  			},
  3896  		},
  3897  		Resources: []ciliumv2.XDSResource{
  3898  			{Any: httpInsecureListenerXDSResource},
  3899  			{Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  3900  				Name: "listener-insecure",
  3901  				VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  3902  					{
  3903  						Name:    "*",
  3904  						Domains: []string{"*"},
  3905  						Routes: []*envoy_config_route_v3.Route{
  3906  							{
  3907  								Match: &envoy_config_route_v3.RouteMatch{
  3908  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3909  										Path: "/multiple-backends-some-missing",
  3910  									},
  3911  								},
  3912  								Action: &envoy_config_route_v3.Route_Route{
  3913  									Route: &envoy_config_route_v3.RouteAction{
  3914  										ClusterSpecifier: &envoy_config_route_v3.RouteAction_WeightedClusters{
  3915  											WeightedClusters: &envoy_config_route_v3.WeightedCluster{
  3916  												Clusters: []*envoy_config_route_v3.WeightedCluster_ClusterWeight{
  3917  													{
  3918  														Name:   "gateway-conformance-infra:infra-backend-v1:8080",
  3919  														Weight: wrapperspb.UInt32(uint32(50)),
  3920  													},
  3921  													{
  3922  														Name:   "gateway-conformance-infra:infra-backend-v2:8080",
  3923  														Weight: wrapperspb.UInt32(uint32(50)),
  3924  														ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3925  															{
  3926  																Header: &envoy_config_core_v3.HeaderValue{
  3927  																	Key:   "X-Header-Add-2",
  3928  																	Value: "header-add-2",
  3929  																},
  3930  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3931  															},
  3932  															{
  3933  																Header: &envoy_config_core_v3.HeaderValue{
  3934  																	Key:   "X-Header-Set-2",
  3935  																	Value: "header-set-2",
  3936  																},
  3937  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3938  															},
  3939  														},
  3940  														ResponseHeadersToRemove: []string{"X-Header-Remove-2"},
  3941  													},
  3942  												},
  3943  											},
  3944  										},
  3945  										MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  3946  											MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  3947  										},
  3948  									},
  3949  								},
  3950  							},
  3951  							{
  3952  								Match: &envoy_config_route_v3.RouteMatch{
  3953  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  3954  										Path: "/multiple-backends-two-filters",
  3955  									},
  3956  								},
  3957  								Action: &envoy_config_route_v3.Route_Route{
  3958  									Route: &envoy_config_route_v3.RouteAction{
  3959  										ClusterSpecifier: &envoy_config_route_v3.RouteAction_WeightedClusters{
  3960  											WeightedClusters: &envoy_config_route_v3.WeightedCluster{
  3961  												Clusters: []*envoy_config_route_v3.WeightedCluster_ClusterWeight{
  3962  													{
  3963  														Name:   "gateway-conformance-infra:infra-backend-v1:8080",
  3964  														Weight: wrapperspb.UInt32(uint32(10)),
  3965  													},
  3966  													{
  3967  														Name:   "gateway-conformance-infra:infra-backend-v2:8080",
  3968  														Weight: wrapperspb.UInt32(uint32(20)),
  3969  														ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3970  															{
  3971  																Header: &envoy_config_core_v3.HeaderValue{
  3972  																	Key:   "X-Header-Add-2",
  3973  																	Value: "header-add-2",
  3974  																},
  3975  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3976  															},
  3977  															{
  3978  																Header: &envoy_config_core_v3.HeaderValue{
  3979  																	Key:   "X-Header-Set-2",
  3980  																	Value: "header-set-2",
  3981  																},
  3982  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  3983  															},
  3984  														},
  3985  														ResponseHeadersToRemove: []string{"X-Header-Remove-2"},
  3986  													},
  3987  													{
  3988  														Name:   "gateway-conformance-infra:infra-backend-v3:8080",
  3989  														Weight: wrapperspb.UInt32(uint32(70)),
  3990  														ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  3991  															{
  3992  																Header: &envoy_config_core_v3.HeaderValue{
  3993  																	Key:   "X-Header-Add-3",
  3994  																	Value: "header-add-3",
  3995  																},
  3996  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  3997  															},
  3998  															{
  3999  																Header: &envoy_config_core_v3.HeaderValue{
  4000  																	Key:   "X-Header-Set-3",
  4001  																	Value: "header-set-3",
  4002  																},
  4003  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4004  															},
  4005  														},
  4006  														ResponseHeadersToRemove: []string{"X-Header-Remove-3"},
  4007  													},
  4008  												},
  4009  											},
  4010  										},
  4011  										MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  4012  											MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  4013  										},
  4014  									},
  4015  								},
  4016  							},
  4017  							{
  4018  								Match: &envoy_config_route_v3.RouteMatch{
  4019  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  4020  										Path: "/multiple-backends",
  4021  									},
  4022  								},
  4023  								Action: &envoy_config_route_v3.Route_Route{
  4024  									Route: &envoy_config_route_v3.RouteAction{
  4025  										ClusterSpecifier: &envoy_config_route_v3.RouteAction_WeightedClusters{
  4026  											WeightedClusters: &envoy_config_route_v3.WeightedCluster{
  4027  												Clusters: []*envoy_config_route_v3.WeightedCluster_ClusterWeight{
  4028  													{
  4029  														Name:   "gateway-conformance-infra:infra-backend-v1:8080",
  4030  														Weight: wrapperspb.UInt32(uint32(50)),
  4031  														ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4032  															{
  4033  																Header: &envoy_config_core_v3.HeaderValue{
  4034  																	Key:   "X-Header-Add-1",
  4035  																	Value: "header-add-1",
  4036  																},
  4037  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4038  															},
  4039  															{
  4040  																Header: &envoy_config_core_v3.HeaderValue{
  4041  																	Key:   "X-Header-Add-1-2",
  4042  																	Value: "header-add-1-2",
  4043  																},
  4044  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4045  															},
  4046  															{
  4047  																Header: &envoy_config_core_v3.HeaderValue{
  4048  																	Key:   "X-Header-Set-1",
  4049  																	Value: "header-set-1",
  4050  																},
  4051  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4052  															},
  4053  															{
  4054  																Header: &envoy_config_core_v3.HeaderValue{
  4055  																	Key:   "X-Header-Set-1-2",
  4056  																	Value: "header-set-1-2",
  4057  																},
  4058  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4059  															},
  4060  														},
  4061  														ResponseHeadersToRemove: []string{"X-Header-Remove-1-1", "X-Header-Remove-1-2"},
  4062  													},
  4063  													{
  4064  														Name:   "gateway-conformance-infra:infra-backend-v2:8080",
  4065  														Weight: wrapperspb.UInt32(uint32(50)),
  4066  														ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4067  															{
  4068  																Header: &envoy_config_core_v3.HeaderValue{
  4069  																	Key:   "X-Header-Add-2",
  4070  																	Value: "header-add-2",
  4071  																},
  4072  																AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4073  															},
  4074  															{
  4075  																Header: &envoy_config_core_v3.HeaderValue{
  4076  																	Key:   "X-Header-Set-2",
  4077  																	Value: "header-set-2",
  4078  																},
  4079  																AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4080  															},
  4081  														},
  4082  														ResponseHeadersToRemove: []string{"X-Header-Remove-2"},
  4083  													},
  4084  												},
  4085  											},
  4086  										},
  4087  										MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  4088  											MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  4089  										},
  4090  									},
  4091  								},
  4092  							},
  4093  							{
  4094  								Match: &envoy_config_route_v3.RouteMatch{
  4095  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  4096  										Path: "/multiple",
  4097  									},
  4098  								},
  4099  								ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4100  									{
  4101  										Header: &envoy_config_core_v3.HeaderValue{
  4102  											Key:   "X-Header-Add-1",
  4103  											Value: "header-add-1",
  4104  										},
  4105  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4106  									},
  4107  									{
  4108  										Header: &envoy_config_core_v3.HeaderValue{
  4109  											Key:   "X-Header-Add-2",
  4110  											Value: "header-add-2",
  4111  										},
  4112  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4113  									},
  4114  									{
  4115  										Header: &envoy_config_core_v3.HeaderValue{
  4116  											Key:   "X-Header-Add-3",
  4117  											Value: "header-add-3",
  4118  										},
  4119  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4120  									},
  4121  									{
  4122  										Header: &envoy_config_core_v3.HeaderValue{
  4123  											Key:   "X-Header-Set-1",
  4124  											Value: "header-set-1",
  4125  										},
  4126  										AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4127  									},
  4128  									{
  4129  										Header: &envoy_config_core_v3.HeaderValue{
  4130  											Key:   "X-Header-Set-2",
  4131  											Value: "header-set-2",
  4132  										},
  4133  										AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4134  									},
  4135  								},
  4136  								ResponseHeadersToRemove: []string{"X-Header-Remove-1", "X-Header-Remove-2"},
  4137  								Action:                  routeActionBackendV1,
  4138  							},
  4139  							{
  4140  								Match: &envoy_config_route_v3.RouteMatch{
  4141  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  4142  										Path: "/remove",
  4143  									},
  4144  								},
  4145  								ResponseHeadersToRemove: []string{"X-Header-Remove"},
  4146  								Action:                  routeActionBackendV1,
  4147  							},
  4148  							{
  4149  								Match: &envoy_config_route_v3.RouteMatch{
  4150  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  4151  										Path: "/set",
  4152  									},
  4153  								},
  4154  								ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4155  									{
  4156  										Header: &envoy_config_core_v3.HeaderValue{
  4157  											Key:   "X-Header-Set",
  4158  											Value: "set-overwrites-values",
  4159  										},
  4160  										AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4161  									},
  4162  								},
  4163  								Action: routeActionBackendV1,
  4164  							},
  4165  							{
  4166  								Match: &envoy_config_route_v3.RouteMatch{
  4167  									PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{
  4168  										Path: "/add",
  4169  									},
  4170  								},
  4171  								ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4172  									{
  4173  										Header: &envoy_config_core_v3.HeaderValue{
  4174  											Key:   "X-Header-Add",
  4175  											Value: "add-appends-values",
  4176  										},
  4177  										AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4178  									},
  4179  								},
  4180  								Action: routeActionBackendV1,
  4181  							},
  4182  						},
  4183  					},
  4184  				},
  4185  			})},
  4186  			{Any: backendV1XDSResource},
  4187  			{Any: backendV2XDSResource},
  4188  			{Any: backendV3XDSResource},
  4189  		},
  4190  	},
  4191  }
  4192  
  4193  // requestRedirectHTTPListeners is the internal representation of the Conformance/HTTPRouteRequestRedirect
  4194  var requestRedirectHTTPListeners = []model.HTTPListener{
  4195  	{
  4196  		Name: "http",
  4197  		Sources: []model.FullyQualifiedResource{
  4198  			{
  4199  				Name:      "same-namespace",
  4200  				Namespace: "gateway-conformance-infra",
  4201  				Group:     "gateway.networking.k8s.io",
  4202  				Version:   "v1",
  4203  				Kind:      "Gateway",
  4204  			},
  4205  		},
  4206  		Port:     80,
  4207  		Hostname: "*",
  4208  		Routes: []model.HTTPRoute{
  4209  			{
  4210  				PathMatch: model.StringMatch{Prefix: "/hostname-redirect"},
  4211  				Backends: []model.Backend{
  4212  					{
  4213  						Name:      "infra-backend-v1",
  4214  						Namespace: "gateway-conformance-infra",
  4215  						Port: &model.BackendPort{
  4216  							Port: 8080,
  4217  						},
  4218  					},
  4219  				},
  4220  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  4221  					Hostname: model.AddressOf("example.com"),
  4222  				},
  4223  			},
  4224  			{
  4225  				PathMatch: model.StringMatch{Prefix: "/status-code-301"},
  4226  				Backends:  []model.Backend{},
  4227  				DirectResponse: &model.DirectResponse{
  4228  					StatusCode: 500,
  4229  				},
  4230  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  4231  					StatusCode: model.AddressOf(301),
  4232  				},
  4233  			},
  4234  			{
  4235  				PathMatch: model.StringMatch{Prefix: "/host-and-status"},
  4236  				Backends: []model.Backend{
  4237  					{
  4238  						Name:      "infra-backend-v1",
  4239  						Namespace: "gateway-conformance-infra",
  4240  						Port: &model.BackendPort{
  4241  							Port: 8080,
  4242  						},
  4243  					},
  4244  				},
  4245  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  4246  					Hostname:   model.AddressOf("example.com"),
  4247  					StatusCode: model.AddressOf(301),
  4248  				},
  4249  			},
  4250  		},
  4251  	},
  4252  }
  4253  
  4254  var requestRedirectHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  4255  	ObjectMeta: metav1.ObjectMeta{
  4256  		Name:      "cilium-gateway-same-namespace",
  4257  		Namespace: "gateway-conformance-infra",
  4258  		Labels: map[string]string{
  4259  			"cilium.io/use-original-source-address":  "false",
  4260  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  4261  		},
  4262  		OwnerReferences: []metav1.OwnerReference{
  4263  			{
  4264  				APIVersion: "gateway.networking.k8s.io/v1",
  4265  				Kind:       "Gateway",
  4266  				Name:       "same-namespace",
  4267  				Controller: model.AddressOf(true),
  4268  			},
  4269  		},
  4270  	},
  4271  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  4272  		Services: []*ciliumv2.ServiceListener{
  4273  			{
  4274  				Name:      "cilium-gateway-same-namespace",
  4275  				Namespace: "gateway-conformance-infra",
  4276  				Ports: []uint16{
  4277  					80,
  4278  				},
  4279  			},
  4280  		},
  4281  		BackendServices: []*ciliumv2.Service{
  4282  			{
  4283  				Name:      "infra-backend-v1",
  4284  				Namespace: "gateway-conformance-infra",
  4285  				Ports:     []string{"8080"},
  4286  			},
  4287  		},
  4288  		Resources: []ciliumv2.XDSResource{
  4289  			{Any: httpInsecureListenerXDSResource},
  4290  			{
  4291  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  4292  					Name: "listener-insecure",
  4293  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  4294  						{
  4295  							Name:    "*",
  4296  							Domains: []string{"*"},
  4297  							Routes: []*envoy_config_route_v3.Route{
  4298  								{
  4299  									Match: &envoy_config_route_v3.RouteMatch{
  4300  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4301  											PathSeparatedPrefix: "/hostname-redirect",
  4302  										},
  4303  									},
  4304  									Action: &envoy_config_route_v3.Route_Redirect{
  4305  										Redirect: &envoy_config_route_v3.RedirectAction{
  4306  											HostRedirect: "example.com",
  4307  											PortRedirect: 80,
  4308  										},
  4309  									},
  4310  								},
  4311  								{
  4312  									Match: &envoy_config_route_v3.RouteMatch{
  4313  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4314  											PathSeparatedPrefix: "/status-code-301",
  4315  										},
  4316  									},
  4317  									Action: &envoy_config_route_v3.Route_Redirect{
  4318  										Redirect: &envoy_config_route_v3.RedirectAction{
  4319  											PortRedirect: 80,
  4320  										},
  4321  									},
  4322  								},
  4323  								{
  4324  									Match: &envoy_config_route_v3.RouteMatch{
  4325  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4326  											PathSeparatedPrefix: "/host-and-status",
  4327  										},
  4328  									},
  4329  									Action: &envoy_config_route_v3.Route_Redirect{
  4330  										Redirect: &envoy_config_route_v3.RedirectAction{
  4331  											HostRedirect: "example.com",
  4332  											PortRedirect: 80,
  4333  										},
  4334  									},
  4335  								},
  4336  							},
  4337  						},
  4338  					},
  4339  				}),
  4340  			},
  4341  			{Any: backendV1XDSResource},
  4342  		},
  4343  	},
  4344  }
  4345  
  4346  // requestRedirectWithMultiHTTPListeners is the internal representation of the Conformance/HTTPRouteRequestRedirect
  4347  var requestRedirectWithMultiHTTPListeners = []model.HTTPListener{
  4348  	{
  4349  		Name: "http",
  4350  		Sources: []model.FullyQualifiedResource{
  4351  			{
  4352  				Name:      "same-namespace",
  4353  				Namespace: "gateway-conformance-infra",
  4354  				Group:     "gateway.networking.k8s.io",
  4355  				Version:   "v1",
  4356  				Kind:      "Gateway",
  4357  			},
  4358  		},
  4359  		Port:     80,
  4360  		Hostname: "example.com",
  4361  		Routes: []model.HTTPRoute{
  4362  			{
  4363  				PathMatch: model.StringMatch{Prefix: "/request-redirect"},
  4364  				Backends: []model.Backend{
  4365  					{
  4366  						Name:      "infra-backend-v1",
  4367  						Namespace: "gateway-conformance-infra",
  4368  						Port: &model.BackendPort{
  4369  							Port: 8080,
  4370  						},
  4371  					},
  4372  				},
  4373  			},
  4374  			{
  4375  				PathMatch: model.StringMatch{Prefix: "/"},
  4376  				DirectResponse: &model.DirectResponse{
  4377  					StatusCode: 500,
  4378  				},
  4379  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  4380  					Hostname:   model.AddressOf("example.com"),
  4381  					Path:       &model.StringMatch{Prefix: "/request-redirect"},
  4382  					StatusCode: model.AddressOf(302),
  4383  					Port:       model.AddressOf(int32(80)),
  4384  				},
  4385  			},
  4386  		},
  4387  	},
  4388  	{
  4389  		Name: "https",
  4390  		Sources: []model.FullyQualifiedResource{
  4391  			{
  4392  				Name:      "same-namespace",
  4393  				Namespace: "gateway-conformance-infra",
  4394  				Group:     "gateway.networking.k8s.io",
  4395  				Version:   "v1",
  4396  				Kind:      "Gateway",
  4397  			},
  4398  		},
  4399  		Port:     443,
  4400  		Hostname: "example.com",
  4401  		Routes: []model.HTTPRoute{
  4402  			{
  4403  				PathMatch: model.StringMatch{Prefix: "/request-redirect"},
  4404  				Backends: []model.Backend{
  4405  					{
  4406  						Name:      "infra-backend-v1",
  4407  						Namespace: "gateway-conformance-infra",
  4408  						Port: &model.BackendPort{
  4409  							Port: 8080,
  4410  						},
  4411  					},
  4412  				},
  4413  			},
  4414  			{
  4415  				PathMatch: model.StringMatch{Prefix: "/"},
  4416  				DirectResponse: &model.DirectResponse{
  4417  					StatusCode: 500,
  4418  				},
  4419  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  4420  					Hostname:   model.AddressOf("example.com"),
  4421  					Path:       &model.StringMatch{Prefix: "/request-redirect"},
  4422  					StatusCode: model.AddressOf(302),
  4423  					Port:       model.AddressOf(int32(443)),
  4424  				},
  4425  			},
  4426  		},
  4427  		TLS: []model.TLSSecret{
  4428  			{
  4429  				Name:      "tls-secure",
  4430  				Namespace: "gateway-conformance-infra",
  4431  			},
  4432  		},
  4433  	},
  4434  }
  4435  
  4436  var requestRedirectWithMultiHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  4437  	ObjectMeta: metav1.ObjectMeta{
  4438  		Name:      "cilium-gateway-same-namespace",
  4439  		Namespace: "gateway-conformance-infra",
  4440  		Labels: map[string]string{
  4441  			"cilium.io/use-original-source-address":  "false",
  4442  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  4443  		},
  4444  		OwnerReferences: []metav1.OwnerReference{
  4445  			{
  4446  				APIVersion: "gateway.networking.k8s.io/v1",
  4447  				Kind:       "Gateway",
  4448  				Name:       "same-namespace",
  4449  				Controller: model.AddressOf(true),
  4450  			},
  4451  		},
  4452  	},
  4453  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  4454  		Services: []*ciliumv2.ServiceListener{
  4455  			{
  4456  				Name:      "cilium-gateway-same-namespace",
  4457  				Namespace: "gateway-conformance-infra",
  4458  				Ports: []uint16{
  4459  					80,
  4460  					443,
  4461  				},
  4462  			},
  4463  		},
  4464  		BackendServices: []*ciliumv2.Service{
  4465  			{
  4466  				Name:      "infra-backend-v1",
  4467  				Namespace: "gateway-conformance-infra",
  4468  				Ports:     []string{"8080"},
  4469  			},
  4470  		},
  4471  		Resources: []ciliumv2.XDSResource{
  4472  			{Any: httpSecureListenerXDSResource},
  4473  			{
  4474  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  4475  					Name: "listener-insecure",
  4476  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  4477  						{
  4478  							Name:    "example.com",
  4479  							Domains: []string{"example.com", "example.com:*"},
  4480  							Routes: []*envoy_config_route_v3.Route{
  4481  								{
  4482  									Match: &envoy_config_route_v3.RouteMatch{
  4483  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4484  											PathSeparatedPrefix: "/request-redirect",
  4485  										},
  4486  									},
  4487  									Action: routeActionBackendV1,
  4488  								},
  4489  								{
  4490  									Match: &envoy_config_route_v3.RouteMatch{
  4491  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  4492  											Prefix: "/",
  4493  										},
  4494  									},
  4495  									Action: &envoy_config_route_v3.Route_Redirect{
  4496  										Redirect: &envoy_config_route_v3.RedirectAction{
  4497  											PortRedirect:         80,
  4498  											HostRedirect:         "example.com",
  4499  											ResponseCode:         envoy_config_route_v3.RedirectAction_FOUND,
  4500  											PathRewriteSpecifier: &envoy_config_route_v3.RedirectAction_PrefixRewrite{PrefixRewrite: "/request-redirect"},
  4501  										},
  4502  									},
  4503  								},
  4504  							},
  4505  						},
  4506  					},
  4507  				}),
  4508  			},
  4509  			{
  4510  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  4511  					Name: "listener-secure",
  4512  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  4513  						{
  4514  							Name:    "example.com",
  4515  							Domains: []string{"example.com", "example.com:*"},
  4516  							Routes: []*envoy_config_route_v3.Route{
  4517  								{
  4518  									Match: &envoy_config_route_v3.RouteMatch{
  4519  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4520  											PathSeparatedPrefix: "/request-redirect",
  4521  										},
  4522  									},
  4523  									Action: routeActionBackendV1,
  4524  								},
  4525  								{
  4526  									Match: &envoy_config_route_v3.RouteMatch{
  4527  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  4528  											Prefix: "/",
  4529  										},
  4530  									},
  4531  									Action: &envoy_config_route_v3.Route_Redirect{
  4532  										Redirect: &envoy_config_route_v3.RedirectAction{
  4533  											PortRedirect:         443,
  4534  											HostRedirect:         "example.com",
  4535  											ResponseCode:         envoy_config_route_v3.RedirectAction_FOUND,
  4536  											PathRewriteSpecifier: &envoy_config_route_v3.RedirectAction_PrefixRewrite{PrefixRewrite: "/request-redirect"},
  4537  										},
  4538  									},
  4539  								},
  4540  							},
  4541  						},
  4542  					},
  4543  				}),
  4544  			},
  4545  			{Any: backendV1XDSResource},
  4546  		},
  4547  	},
  4548  }
  4549  
  4550  // responseHeaderModifierHTTPListeners is the internal representation of the Conformance/HTTPRouteResponseHeaderModifier
  4551  var responseHeaderModifierHTTPListeners = []model.HTTPListener{
  4552  	{
  4553  		Name: "http",
  4554  		Sources: []model.FullyQualifiedResource{
  4555  			{
  4556  				Name:      "same-namespace",
  4557  				Namespace: "gateway-conformance-infra",
  4558  				Group:     "gateway.networking.k8s.io",
  4559  				Version:   "v1",
  4560  				Kind:      "Gateway",
  4561  			},
  4562  		},
  4563  		Port: 80, Hostname: "*",
  4564  		Routes: []model.HTTPRoute{
  4565  			{
  4566  				PathMatch: model.StringMatch{Prefix: "/set"},
  4567  				Backends: []model.Backend{
  4568  					{
  4569  						Name:      "infra-backend-v1",
  4570  						Namespace: "gateway-conformance-infra",
  4571  						Port: &model.BackendPort{
  4572  							Port: 8080,
  4573  						},
  4574  					},
  4575  				},
  4576  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  4577  					HeadersToSet: []model.Header{
  4578  						{
  4579  							Name:  "X-Header-Set",
  4580  							Value: "set-overwrites-values",
  4581  						},
  4582  					},
  4583  				},
  4584  			},
  4585  			{
  4586  				PathMatch: model.StringMatch{Prefix: "/add"},
  4587  				Backends: []model.Backend{
  4588  					{
  4589  						Name:      "infra-backend-v1",
  4590  						Namespace: "gateway-conformance-infra",
  4591  						Port: &model.BackendPort{
  4592  							Port: 8080,
  4593  						},
  4594  					},
  4595  				},
  4596  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  4597  					HeadersToAdd: []model.Header{
  4598  						{
  4599  							Name:  "X-Header-Add",
  4600  							Value: "add-appends-values",
  4601  						},
  4602  					},
  4603  				},
  4604  			},
  4605  			{
  4606  				PathMatch: model.StringMatch{Prefix: "/remove"},
  4607  				Backends: []model.Backend{
  4608  					{
  4609  						Name:      "infra-backend-v1",
  4610  						Namespace: "gateway-conformance-infra",
  4611  						Port: &model.BackendPort{
  4612  							Port: 8080,
  4613  						},
  4614  					},
  4615  				},
  4616  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  4617  					HeadersToRemove: []string{"X-Header-Remove"},
  4618  				},
  4619  			},
  4620  			{
  4621  				PathMatch: model.StringMatch{Prefix: "/multiple"},
  4622  				Backends: []model.Backend{
  4623  					{
  4624  						Name:      "infra-backend-v1",
  4625  						Namespace: "gateway-conformance-infra",
  4626  						Port: &model.BackendPort{
  4627  							Port: 8080,
  4628  						},
  4629  					},
  4630  				},
  4631  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  4632  					HeadersToAdd: []model.Header{
  4633  						{
  4634  							Name:  "X-Header-Add-1",
  4635  							Value: "header-add-1",
  4636  						},
  4637  						{
  4638  							Name:  "X-Header-Add-2",
  4639  							Value: "header-add-2",
  4640  						},
  4641  						{
  4642  							Name:  "X-Header-Add-3",
  4643  							Value: "header-add-3",
  4644  						},
  4645  					},
  4646  					HeadersToSet: []model.Header{
  4647  						{
  4648  							Name:  "X-Header-Set-1",
  4649  							Value: "header-set-1",
  4650  						},
  4651  						{
  4652  							Name:  "X-Header-Set-2",
  4653  							Value: "header-set-2",
  4654  						},
  4655  					},
  4656  					HeadersToRemove: []string{
  4657  						"X-Header-Remove-1",
  4658  						"X-Header-Remove-2",
  4659  					},
  4660  				},
  4661  			},
  4662  			{
  4663  				PathMatch: model.StringMatch{Prefix: "/case-insensitivity"},
  4664  				Backends: []model.Backend{
  4665  					{
  4666  						Name:      "infra-backend-v1",
  4667  						Namespace: "gateway-conformance-infra",
  4668  						Port: &model.BackendPort{
  4669  							Port: 8080,
  4670  						},
  4671  					},
  4672  				},
  4673  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  4674  					HeadersToAdd: []model.Header{
  4675  						{
  4676  							Name:  "X-Header-Add",
  4677  							Value: "header-add",
  4678  						},
  4679  						{
  4680  							Name:  "x-lowercase-add",
  4681  							Value: "lowercase-add",
  4682  						},
  4683  						{
  4684  							Name:  "x-Mixedcase-ADD-1",
  4685  							Value: "mixedcase-add-1",
  4686  						},
  4687  						{
  4688  							Name:  "X-mixeDcase-add-2",
  4689  							Value: "mixedcase-add-2",
  4690  						},
  4691  						{
  4692  							Name:  "X-UPPERCASE-ADD",
  4693  							Value: "uppercase-add",
  4694  						},
  4695  					},
  4696  					HeadersToSet: []model.Header{
  4697  						{
  4698  							Name:  "X-Header-Set",
  4699  							Value: "header-set",
  4700  						},
  4701  					},
  4702  					HeadersToRemove: []string{
  4703  						"X-Header-Remove",
  4704  					},
  4705  				},
  4706  			},
  4707  		},
  4708  	},
  4709  }
  4710  
  4711  var responseHeaderModifierHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  4712  	ObjectMeta: metav1.ObjectMeta{
  4713  		Name:      "cilium-gateway-same-namespace",
  4714  		Namespace: "gateway-conformance-infra",
  4715  		Labels: map[string]string{
  4716  			"cilium.io/use-original-source-address":  "false",
  4717  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  4718  		},
  4719  		OwnerReferences: []metav1.OwnerReference{
  4720  			{
  4721  				APIVersion: "gateway.networking.k8s.io/v1",
  4722  				Kind:       "Gateway",
  4723  				Name:       "same-namespace",
  4724  				Controller: model.AddressOf(true),
  4725  			},
  4726  		},
  4727  	},
  4728  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  4729  		Services: []*ciliumv2.ServiceListener{
  4730  			{
  4731  				Name:      "cilium-gateway-same-namespace",
  4732  				Namespace: "gateway-conformance-infra",
  4733  				Ports: []uint16{
  4734  					80,
  4735  				},
  4736  			},
  4737  		},
  4738  		BackendServices: []*ciliumv2.Service{
  4739  			{
  4740  				Name:      "infra-backend-v1",
  4741  				Namespace: "gateway-conformance-infra",
  4742  				Ports:     []string{"8080"},
  4743  			},
  4744  		},
  4745  		Resources: []ciliumv2.XDSResource{
  4746  			{Any: httpInsecureListenerXDSResource},
  4747  			{
  4748  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  4749  					Name: "listener-insecure",
  4750  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  4751  						{
  4752  							Name:    "*",
  4753  							Domains: []string{"*"},
  4754  							Routes: []*envoy_config_route_v3.Route{
  4755  								{
  4756  									Match: &envoy_config_route_v3.RouteMatch{
  4757  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4758  											PathSeparatedPrefix: "/case-insensitivity",
  4759  										},
  4760  									},
  4761  									ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4762  										{
  4763  											Header: &envoy_config_core_v3.HeaderValue{
  4764  												Key:   "X-Header-Add",
  4765  												Value: "header-add",
  4766  											},
  4767  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4768  										},
  4769  										{
  4770  											Header: &envoy_config_core_v3.HeaderValue{
  4771  												Key:   "x-lowercase-add",
  4772  												Value: "lowercase-add",
  4773  											},
  4774  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4775  										},
  4776  										{
  4777  											Header: &envoy_config_core_v3.HeaderValue{
  4778  												Key:   "x-Mixedcase-ADD-1",
  4779  												Value: "mixedcase-add-1",
  4780  											},
  4781  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4782  										},
  4783  										{
  4784  											Header: &envoy_config_core_v3.HeaderValue{
  4785  												Key:   "X-mixeDcase-add-2",
  4786  												Value: "mixedcase-add-2",
  4787  											},
  4788  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4789  										},
  4790  										{
  4791  											Header: &envoy_config_core_v3.HeaderValue{
  4792  												Key:   "X-UPPERCASE-ADD",
  4793  												Value: "uppercase-add",
  4794  											},
  4795  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4796  										},
  4797  										{
  4798  											Header: &envoy_config_core_v3.HeaderValue{
  4799  												Key:   "X-Header-Set",
  4800  												Value: "header-set",
  4801  											},
  4802  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4803  										},
  4804  									},
  4805  									ResponseHeadersToRemove: []string{"X-Header-Remove"},
  4806  									Action:                  routeActionBackendV1,
  4807  								},
  4808  								{
  4809  									Match: &envoy_config_route_v3.RouteMatch{
  4810  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4811  											PathSeparatedPrefix: "/multiple",
  4812  										},
  4813  									},
  4814  									ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4815  										{
  4816  											Header: &envoy_config_core_v3.HeaderValue{
  4817  												Key:   "X-Header-Add-1",
  4818  												Value: "header-add-1",
  4819  											},
  4820  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4821  										},
  4822  										{
  4823  											Header: &envoy_config_core_v3.HeaderValue{
  4824  												Key:   "X-Header-Add-2",
  4825  												Value: "header-add-2",
  4826  											},
  4827  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4828  										},
  4829  										{
  4830  											Header: &envoy_config_core_v3.HeaderValue{
  4831  												Key:   "X-Header-Add-3",
  4832  												Value: "header-add-3",
  4833  											},
  4834  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4835  										},
  4836  										{
  4837  											Header: &envoy_config_core_v3.HeaderValue{
  4838  												Key:   "X-Header-Set-1",
  4839  												Value: "header-set-1",
  4840  											},
  4841  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4842  										},
  4843  										{
  4844  											Header: &envoy_config_core_v3.HeaderValue{
  4845  												Key:   "X-Header-Set-2",
  4846  												Value: "header-set-2",
  4847  											},
  4848  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4849  										},
  4850  									},
  4851  									ResponseHeadersToRemove: []string{"X-Header-Remove-1", "X-Header-Remove-2"},
  4852  									Action:                  routeActionBackendV1,
  4853  								},
  4854  								{
  4855  									Match: &envoy_config_route_v3.RouteMatch{
  4856  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4857  											PathSeparatedPrefix: "/remove",
  4858  										},
  4859  									},
  4860  									ResponseHeadersToRemove: []string{"X-Header-Remove"},
  4861  									Action:                  routeActionBackendV1,
  4862  								},
  4863  								{
  4864  									Match: &envoy_config_route_v3.RouteMatch{
  4865  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4866  											PathSeparatedPrefix: "/set",
  4867  										},
  4868  									},
  4869  									ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4870  										{
  4871  											Header: &envoy_config_core_v3.HeaderValue{
  4872  												Key:   "X-Header-Set",
  4873  												Value: "set-overwrites-values",
  4874  											},
  4875  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  4876  										},
  4877  									},
  4878  									Action: routeActionBackendV1,
  4879  								},
  4880  								{
  4881  									Match: &envoy_config_route_v3.RouteMatch{
  4882  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  4883  											PathSeparatedPrefix: "/add",
  4884  										},
  4885  									},
  4886  									ResponseHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  4887  										{
  4888  											Header: &envoy_config_core_v3.HeaderValue{
  4889  												Key:   "X-Header-Add",
  4890  												Value: "add-appends-values",
  4891  											},
  4892  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  4893  										},
  4894  									},
  4895  									Action: routeActionBackendV1,
  4896  								},
  4897  							},
  4898  						},
  4899  					},
  4900  				}),
  4901  			},
  4902  			{Any: backendV1XDSResource},
  4903  		},
  4904  	},
  4905  }
  4906  
  4907  // rewriteHostHTTPListeners is the internal representation of the Conformance/HTTPRouteRewriteHost
  4908  var rewriteHostHTTPListeners = []model.HTTPListener{
  4909  	{
  4910  		Name: "http",
  4911  		Sources: []model.FullyQualifiedResource{
  4912  			{
  4913  				Name:      "same-namespace",
  4914  				Namespace: "gateway-conformance-infra",
  4915  				Group:     "gateway.networking.k8s.io",
  4916  				Version:   "v1",
  4917  				Kind:      "Gateway",
  4918  			},
  4919  		},
  4920  		Port:     80,
  4921  		Hostname: "*",
  4922  		Routes: []model.HTTPRoute{
  4923  			{
  4924  				Hostnames: []string{"rewrite.example"},
  4925  				PathMatch: model.StringMatch{Prefix: "/one"},
  4926  				Backends: []model.Backend{
  4927  					{
  4928  						Name:      "infra-backend-v1",
  4929  						Namespace: "gateway-conformance-infra",
  4930  						Port: &model.BackendPort{
  4931  							Port: 8080,
  4932  						},
  4933  					},
  4934  				},
  4935  				Rewrite: &model.HTTPURLRewriteFilter{
  4936  					HostName: model.AddressOf("one.example.org"),
  4937  				},
  4938  			},
  4939  			{
  4940  				Hostnames: []string{"rewrite.example"},
  4941  				Backends: []model.Backend{
  4942  					{
  4943  						Name:      "infra-backend-v2",
  4944  						Namespace: "gateway-conformance-infra",
  4945  						Port: &model.BackendPort{
  4946  							Port: 8080,
  4947  						},
  4948  					},
  4949  				},
  4950  				Rewrite: &model.HTTPURLRewriteFilter{
  4951  					HostName: model.AddressOf("example.org"),
  4952  				},
  4953  			},
  4954  		},
  4955  	},
  4956  }
  4957  
  4958  var rewriteHostHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  4959  	ObjectMeta: metav1.ObjectMeta{
  4960  		Name:      "cilium-gateway-same-namespace",
  4961  		Namespace: "gateway-conformance-infra",
  4962  		Labels: map[string]string{
  4963  			"cilium.io/use-original-source-address":  "false",
  4964  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  4965  		},
  4966  		OwnerReferences: []metav1.OwnerReference{
  4967  			{
  4968  				APIVersion: "gateway.networking.k8s.io/v1",
  4969  				Kind:       "Gateway",
  4970  				Name:       "same-namespace",
  4971  				Controller: model.AddressOf(true),
  4972  			},
  4973  		},
  4974  	},
  4975  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  4976  		Services: []*ciliumv2.ServiceListener{
  4977  			{
  4978  				Name:      "cilium-gateway-same-namespace",
  4979  				Namespace: "gateway-conformance-infra",
  4980  				Ports: []uint16{
  4981  					80,
  4982  				},
  4983  			},
  4984  		},
  4985  		BackendServices: []*ciliumv2.Service{
  4986  			{
  4987  				Name:      "infra-backend-v1",
  4988  				Namespace: "gateway-conformance-infra",
  4989  				Ports:     []string{"8080"},
  4990  			},
  4991  			{
  4992  				Name:      "infra-backend-v2",
  4993  				Namespace: "gateway-conformance-infra",
  4994  				Ports:     []string{"8080"},
  4995  			},
  4996  		},
  4997  		Resources: []ciliumv2.XDSResource{
  4998  			{Any: httpInsecureListenerXDSResource},
  4999  			{
  5000  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  5001  					Name: "listener-insecure",
  5002  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  5003  						{
  5004  							Name:    "rewrite.example",
  5005  							Domains: []string{"rewrite.example", "rewrite.example:*"},
  5006  							Routes: []*envoy_config_route_v3.Route{
  5007  								{
  5008  									Match: &envoy_config_route_v3.RouteMatch{
  5009  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  5010  											PathSeparatedPrefix: "/one",
  5011  										},
  5012  									},
  5013  									Action: &envoy_config_route_v3.Route_Route{
  5014  										Route: &envoy_config_route_v3.RouteAction{
  5015  											ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5016  												Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v1", "8080"),
  5017  											},
  5018  											HostRewriteSpecifier: &envoy_config_route_v3.RouteAction_HostRewriteLiteral{
  5019  												HostRewriteLiteral: "one.example.org",
  5020  											},
  5021  											MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5022  												MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5023  											},
  5024  										},
  5025  									},
  5026  								},
  5027  								{
  5028  									Match: &envoy_config_route_v3.RouteMatch{
  5029  										PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
  5030  											Prefix: "/",
  5031  										},
  5032  									},
  5033  									Action: &envoy_config_route_v3.Route_Route{
  5034  										Route: &envoy_config_route_v3.RouteAction{
  5035  											ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5036  												Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v2", "8080"),
  5037  											},
  5038  											HostRewriteSpecifier: &envoy_config_route_v3.RouteAction_HostRewriteLiteral{
  5039  												HostRewriteLiteral: "example.org",
  5040  											},
  5041  											MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5042  												MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5043  											},
  5044  										},
  5045  									},
  5046  								},
  5047  							},
  5048  						},
  5049  					},
  5050  				}),
  5051  			},
  5052  			{Any: backendV1XDSResource},
  5053  			{Any: backendV2XDSResource},
  5054  		},
  5055  	},
  5056  }
  5057  
  5058  // rewritePathHTTPListeners is the internal representation of the Conformance/HTTPRouteRewritePath
  5059  var rewritePathHTTPListeners = []model.HTTPListener{
  5060  	{
  5061  		Name: "http",
  5062  		Sources: []model.FullyQualifiedResource{
  5063  			{
  5064  				Name:      "same-namespace",
  5065  				Namespace: "gateway-conformance-infra",
  5066  				Group:     "gateway.networking.k8s.io",
  5067  				Version:   "v1",
  5068  				Kind:      "Gateway",
  5069  			},
  5070  		},
  5071  		Port:     80,
  5072  		Hostname: "*",
  5073  		Routes: []model.HTTPRoute{
  5074  			{
  5075  				PathMatch: model.StringMatch{Prefix: "/prefix/one"},
  5076  				Backends: []model.Backend{
  5077  					{
  5078  						Name:      "infra-backend-v1",
  5079  						Namespace: "gateway-conformance-infra",
  5080  						Port: &model.BackendPort{
  5081  							Port: 8080,
  5082  						},
  5083  					},
  5084  				},
  5085  				Rewrite: &model.HTTPURLRewriteFilter{
  5086  					Path: &model.StringMatch{
  5087  						Prefix: "/one",
  5088  					},
  5089  				},
  5090  			},
  5091  			{
  5092  				PathMatch: model.StringMatch{Prefix: "/full/one"},
  5093  				Backends: []model.Backend{
  5094  					{
  5095  						Name:      "infra-backend-v1",
  5096  						Namespace: "gateway-conformance-infra",
  5097  						Port: &model.BackendPort{
  5098  							Port: 8080,
  5099  						},
  5100  					},
  5101  				},
  5102  				Rewrite: &model.HTTPURLRewriteFilter{
  5103  					Path: &model.StringMatch{
  5104  						Exact: "/one",
  5105  					},
  5106  				},
  5107  			},
  5108  			{
  5109  				PathMatch: model.StringMatch{Prefix: "/full/rewrite-path-and-modify-headers"},
  5110  				Backends: []model.Backend{
  5111  					{
  5112  						Name:      "infra-backend-v1",
  5113  						Namespace: "gateway-conformance-infra",
  5114  						Port: &model.BackendPort{
  5115  							Port: 8080,
  5116  						},
  5117  					},
  5118  				},
  5119  				Rewrite: &model.HTTPURLRewriteFilter{
  5120  					Path: &model.StringMatch{
  5121  						Exact: "/test",
  5122  					},
  5123  				},
  5124  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  5125  					HeadersToAdd: []model.Header{
  5126  						{
  5127  							Name:  "X-Header-Add",
  5128  							Value: "header-val-1",
  5129  						},
  5130  						{
  5131  							Name:  "X-Header-Add-Append",
  5132  							Value: "header-val-2",
  5133  						},
  5134  					},
  5135  					HeadersToSet: []model.Header{
  5136  						{
  5137  							Name:  "X-Header-Set",
  5138  							Value: "set-overwrites-values",
  5139  						},
  5140  					},
  5141  					HeadersToRemove: []string{"X-Header-Remove"},
  5142  				},
  5143  			},
  5144  			{
  5145  				PathMatch: model.StringMatch{Prefix: "/prefix/rewrite-path-and-modify-headers"},
  5146  				Backends: []model.Backend{
  5147  					{
  5148  						Name:      "infra-backend-v1",
  5149  						Namespace: "gateway-conformance-infra",
  5150  						Port: &model.BackendPort{
  5151  							Port: 8080,
  5152  						},
  5153  					},
  5154  				},
  5155  				Rewrite: &model.HTTPURLRewriteFilter{
  5156  					Path: &model.StringMatch{
  5157  						Prefix: "/prefix",
  5158  					},
  5159  				},
  5160  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  5161  					HeadersToAdd: []model.Header{
  5162  						{
  5163  							Name:  "X-Header-Add",
  5164  							Value: "header-val-1",
  5165  						},
  5166  						{
  5167  							Name:  "X-Header-Add-Append",
  5168  							Value: "header-val-2",
  5169  						},
  5170  					},
  5171  					HeadersToSet: []model.Header{
  5172  						{
  5173  							Name:  "X-Header-Set",
  5174  							Value: "set-overwrites-values",
  5175  						},
  5176  					},
  5177  					HeadersToRemove: []string{"X-Header-Remove"},
  5178  				},
  5179  			},
  5180  		},
  5181  	},
  5182  }
  5183  
  5184  var rewritePathHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  5185  	ObjectMeta: metav1.ObjectMeta{
  5186  		Name:      "cilium-gateway-same-namespace",
  5187  		Namespace: "gateway-conformance-infra",
  5188  		Labels: map[string]string{
  5189  			"cilium.io/use-original-source-address":  "false",
  5190  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  5191  		},
  5192  		OwnerReferences: []metav1.OwnerReference{
  5193  			{
  5194  				APIVersion: "gateway.networking.k8s.io/v1",
  5195  				Kind:       "Gateway",
  5196  				Name:       "same-namespace",
  5197  				Controller: model.AddressOf(true),
  5198  			},
  5199  		},
  5200  	},
  5201  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  5202  		Services: []*ciliumv2.ServiceListener{
  5203  			{
  5204  				Name:      "cilium-gateway-same-namespace",
  5205  				Namespace: "gateway-conformance-infra",
  5206  				Ports: []uint16{
  5207  					80,
  5208  				},
  5209  			},
  5210  		},
  5211  		BackendServices: []*ciliumv2.Service{
  5212  			{
  5213  				Name:      "infra-backend-v1",
  5214  				Namespace: "gateway-conformance-infra",
  5215  				Ports:     []string{"8080"},
  5216  			},
  5217  		},
  5218  		Resources: []ciliumv2.XDSResource{
  5219  			{Any: httpInsecureListenerXDSResource},
  5220  			{
  5221  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  5222  					Name: "listener-insecure",
  5223  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  5224  						{
  5225  							Name:    "*",
  5226  							Domains: []string{"*"},
  5227  							Routes: []*envoy_config_route_v3.Route{
  5228  								{
  5229  									Match: &envoy_config_route_v3.RouteMatch{
  5230  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  5231  											PathSeparatedPrefix: "/prefix/rewrite-path-and-modify-headers",
  5232  										},
  5233  									},
  5234  									Action: &envoy_config_route_v3.Route_Route{
  5235  										Route: &envoy_config_route_v3.RouteAction{
  5236  											ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5237  												Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v1", "8080"),
  5238  											},
  5239  											PrefixRewrite: "/prefix",
  5240  											MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5241  												MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5242  											},
  5243  										},
  5244  									},
  5245  									RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  5246  										{
  5247  											Header: &envoy_config_core_v3.HeaderValue{
  5248  												Key:   "X-Header-Add",
  5249  												Value: "header-val-1",
  5250  											},
  5251  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  5252  										},
  5253  										{
  5254  											Header: &envoy_config_core_v3.HeaderValue{
  5255  												Key:   "X-Header-Add-Append",
  5256  												Value: "header-val-2",
  5257  											},
  5258  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  5259  										},
  5260  										{
  5261  											Header: &envoy_config_core_v3.HeaderValue{
  5262  												Key:   "X-Header-Set",
  5263  												Value: "set-overwrites-values",
  5264  											},
  5265  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  5266  										},
  5267  									},
  5268  									RequestHeadersToRemove: []string{"X-Header-Remove"},
  5269  								},
  5270  								{
  5271  									Match: &envoy_config_route_v3.RouteMatch{
  5272  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  5273  											PathSeparatedPrefix: "/full/rewrite-path-and-modify-headers",
  5274  										},
  5275  									},
  5276  									Action: &envoy_config_route_v3.Route_Route{
  5277  										Route: &envoy_config_route_v3.RouteAction{
  5278  											ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5279  												Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v1", "8080"),
  5280  											},
  5281  											RegexRewrite: &envoy_type_matcher_v3.RegexMatchAndSubstitute{
  5282  												Pattern: &envoy_type_matcher_v3.RegexMatcher{
  5283  													Regex: "^/.*$",
  5284  												},
  5285  												Substitution: "/test",
  5286  											},
  5287  											MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5288  												MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5289  											},
  5290  										},
  5291  									},
  5292  									RequestHeadersToAdd: []*envoy_config_core_v3.HeaderValueOption{
  5293  										{
  5294  											Header: &envoy_config_core_v3.HeaderValue{
  5295  												Key:   "X-Header-Add",
  5296  												Value: "header-val-1",
  5297  											},
  5298  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  5299  										},
  5300  										{
  5301  											Header: &envoy_config_core_v3.HeaderValue{
  5302  												Key:   "X-Header-Add-Append",
  5303  												Value: "header-val-2",
  5304  											},
  5305  											AppendAction: envoy_config_core_v3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,
  5306  										},
  5307  										{
  5308  											Header: &envoy_config_core_v3.HeaderValue{
  5309  												Key:   "X-Header-Set",
  5310  												Value: "set-overwrites-values",
  5311  											},
  5312  											AppendAction: envoy_config_core_v3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  5313  										},
  5314  									},
  5315  									RequestHeadersToRemove: []string{"X-Header-Remove"},
  5316  								},
  5317  								{
  5318  									Match: &envoy_config_route_v3.RouteMatch{
  5319  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  5320  											PathSeparatedPrefix: "/prefix/one",
  5321  										},
  5322  									},
  5323  									Action: &envoy_config_route_v3.Route_Route{
  5324  										Route: &envoy_config_route_v3.RouteAction{
  5325  											ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5326  												Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v1", "8080"),
  5327  											},
  5328  											PrefixRewrite: "/one",
  5329  											MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5330  												MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5331  											},
  5332  										},
  5333  									},
  5334  								},
  5335  								{
  5336  									Match: &envoy_config_route_v3.RouteMatch{
  5337  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  5338  											PathSeparatedPrefix: "/full/one",
  5339  										},
  5340  									},
  5341  									Action: &envoy_config_route_v3.Route_Route{
  5342  										Route: &envoy_config_route_v3.RouteAction{
  5343  											ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5344  												Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v1", "8080"),
  5345  											},
  5346  											RegexRewrite: &envoy_type_matcher_v3.RegexMatchAndSubstitute{
  5347  												Pattern: &envoy_type_matcher_v3.RegexMatcher{
  5348  													Regex: "^/.*$",
  5349  												},
  5350  												Substitution: "/one",
  5351  											},
  5352  											MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5353  												MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5354  											},
  5355  										},
  5356  									},
  5357  								},
  5358  							},
  5359  						},
  5360  					},
  5361  				}),
  5362  			},
  5363  			{Any: backendV1XDSResource},
  5364  		},
  5365  	},
  5366  }
  5367  
  5368  // mirrorHTTPListeners is the internal representation of the Conformance/HTTPRouteRequestMirror
  5369  var mirrorHTTPListeners = []model.HTTPListener{
  5370  	{
  5371  		Name: "http",
  5372  		Sources: []model.FullyQualifiedResource{
  5373  			{
  5374  				Name:      "same-namespace",
  5375  				Namespace: "gateway-conformance-infra",
  5376  				Group:     "gateway.networking.k8s.io",
  5377  				Version:   "v1",
  5378  				Kind:      "Gateway",
  5379  			},
  5380  		},
  5381  		Port:     80,
  5382  		Hostname: "*",
  5383  		Routes: []model.HTTPRoute{
  5384  			{
  5385  				PathMatch: model.StringMatch{Prefix: "/mirror"},
  5386  				Backends: []model.Backend{
  5387  					{
  5388  						Name:      "infra-backend-v1",
  5389  						Namespace: "gateway-conformance-infra",
  5390  						Port: &model.BackendPort{
  5391  							Port: 8080,
  5392  						},
  5393  					},
  5394  				},
  5395  				RequestMirrors: []*model.HTTPRequestMirror{
  5396  					{
  5397  						Backend: &model.Backend{
  5398  							Name:      "infra-backend-v2",
  5399  							Namespace: "gateway-conformance-infra",
  5400  							Port: &model.BackendPort{
  5401  								Port: 8080,
  5402  							},
  5403  						},
  5404  					},
  5405  				},
  5406  			},
  5407  		},
  5408  	},
  5409  }
  5410  
  5411  var mirrorHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
  5412  	ObjectMeta: metav1.ObjectMeta{
  5413  		Name:      "cilium-gateway-same-namespace",
  5414  		Namespace: "gateway-conformance-infra",
  5415  		Labels: map[string]string{
  5416  			"cilium.io/use-original-source-address":  "false",
  5417  			"gateway.networking.k8s.io/gateway-name": "same-namespace",
  5418  		},
  5419  		OwnerReferences: []metav1.OwnerReference{
  5420  			{
  5421  				APIVersion: "gateway.networking.k8s.io/v1",
  5422  				Kind:       "Gateway",
  5423  				Name:       "same-namespace",
  5424  				Controller: model.AddressOf(true),
  5425  			},
  5426  		},
  5427  	},
  5428  	Spec: ciliumv2.CiliumEnvoyConfigSpec{
  5429  		Services: []*ciliumv2.ServiceListener{
  5430  			{
  5431  				Name:      "cilium-gateway-same-namespace",
  5432  				Namespace: "gateway-conformance-infra",
  5433  				Ports: []uint16{
  5434  					80,
  5435  				},
  5436  			},
  5437  		},
  5438  		BackendServices: []*ciliumv2.Service{
  5439  			{
  5440  				Name:      "infra-backend-v1",
  5441  				Namespace: "gateway-conformance-infra",
  5442  				Ports:     []string{"8080"},
  5443  			},
  5444  			{
  5445  				Name:      "infra-backend-v2",
  5446  				Namespace: "gateway-conformance-infra",
  5447  				Ports:     []string{"8080"},
  5448  			},
  5449  		},
  5450  		Resources: []ciliumv2.XDSResource{
  5451  			{Any: httpInsecureListenerXDSResource},
  5452  			{
  5453  				Any: toAny(&envoy_config_route_v3.RouteConfiguration{
  5454  					Name: "listener-insecure",
  5455  					VirtualHosts: []*envoy_config_route_v3.VirtualHost{
  5456  						{
  5457  							Name:    "*",
  5458  							Domains: []string{"*"},
  5459  							Routes: []*envoy_config_route_v3.Route{
  5460  								{
  5461  									Match: &envoy_config_route_v3.RouteMatch{
  5462  										PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
  5463  											PathSeparatedPrefix: "/mirror",
  5464  										},
  5465  									},
  5466  									Action: &envoy_config_route_v3.Route_Route{
  5467  										Route: &envoy_config_route_v3.RouteAction{
  5468  											ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5469  												Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v1", "8080"),
  5470  											},
  5471  											RequestMirrorPolicies: []*envoy_config_route_v3.RouteAction_RequestMirrorPolicy{
  5472  												{
  5473  													Cluster: fmt.Sprintf("%s:%s:%s", "gateway-conformance-infra", "infra-backend-v2", "8080"),
  5474  													RuntimeFraction: &envoy_config_core_v3.RuntimeFractionalPercent{
  5475  														DefaultValue: &envoy_type_v3.FractionalPercent{
  5476  															Numerator: 100,
  5477  														},
  5478  													},
  5479  												},
  5480  											},
  5481  											MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5482  												MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5483  											},
  5484  										},
  5485  									},
  5486  								},
  5487  							},
  5488  						},
  5489  					},
  5490  				}),
  5491  			},
  5492  			{Any: backendV1XDSResource},
  5493  			{Any: backendV2XDSResource},
  5494  		},
  5495  	},
  5496  }
  5497  
  5498  var multipleListenerGatewayListeners = []model.HTTPListener{
  5499  	{
  5500  		Name: "http-example",
  5501  		Sources: []model.FullyQualifiedResource{
  5502  			{
  5503  				Name:      "my-gateway",
  5504  				Namespace: "default",
  5505  				Group:     "gateway.networking.k8s.io",
  5506  				Version:   "v1",
  5507  				Kind:      "Gateway",
  5508  			},
  5509  		},
  5510  		Address:  "",
  5511  		Port:     80,
  5512  		Hostname: "example.com",
  5513  		Routes: []model.HTTPRoute{
  5514  			{
  5515  				Hostnames: []string{"example.com"},
  5516  				DirectResponse: &model.DirectResponse{
  5517  					StatusCode: 500,
  5518  				},
  5519  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  5520  					Scheme:     model.AddressOf("https"),
  5521  					StatusCode: model.AddressOf(301),
  5522  				},
  5523  				Backends: []model.Backend{},
  5524  			},
  5525  		},
  5526  	},
  5527  	{
  5528  		Name: "https-example",
  5529  		Sources: []model.FullyQualifiedResource{
  5530  			{
  5531  				Name:      "my-gateway",
  5532  				Namespace: "default",
  5533  				Group:     "gateway.networking.k8s.io",
  5534  				Version:   "v1",
  5535  				Kind:      "Gateway",
  5536  			},
  5537  		},
  5538  		Address:  "",
  5539  		Port:     443,
  5540  		Hostname: "example.com",
  5541  		TLS: []model.TLSSecret{
  5542  			{
  5543  				Name:      "example-cert",
  5544  				Namespace: "default",
  5545  			},
  5546  		},
  5547  		Routes: []model.HTTPRoute{
  5548  			{
  5549  				Hostnames: []string{"example.com"},
  5550  				Backends: []model.Backend{
  5551  					{
  5552  						Name:      "my-service",
  5553  						Namespace: "default",
  5554  						Port: &model.BackendPort{
  5555  							Port: 8080,
  5556  						},
  5557  					},
  5558  				},
  5559  			},
  5560  		},
  5561  	},
  5562  }
  5563  
  5564  func toEnvoyCluster(namespace, name, port string) *envoy_config_cluster_v3.Cluster {
  5565  	return &envoy_config_cluster_v3.Cluster{
  5566  		Name: fmt.Sprintf("%s:%s:%s", namespace, name, port),
  5567  		EdsClusterConfig: &envoy_config_cluster_v3.Cluster_EdsClusterConfig{
  5568  			ServiceName: fmt.Sprintf("%s/%s:%s", namespace, name, port),
  5569  		},
  5570  		TypedExtensionProtocolOptions: map[string]*anypb.Any{
  5571  			"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": toAny(&envoy_upstreams_http_v3.HttpProtocolOptions{
  5572  				CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{
  5573  					IdleTimeout: &durationpb.Duration{Seconds: int64(60)},
  5574  				},
  5575  				UpstreamProtocolOptions: &envoy_upstreams_http_v3.HttpProtocolOptions_UseDownstreamProtocolConfig{
  5576  					UseDownstreamProtocolConfig: &envoy_upstreams_http_v3.HttpProtocolOptions_UseDownstreamHttpConfig{
  5577  						Http2ProtocolOptions: &envoy_config_core_v3.Http2ProtocolOptions{},
  5578  					},
  5579  				},
  5580  			}),
  5581  		},
  5582  		ClusterDiscoveryType: &envoy_config_cluster_v3.Cluster_Type{
  5583  			Type: envoy_config_cluster_v3.Cluster_EDS,
  5584  		},
  5585  		ConnectTimeout: &durationpb.Duration{Seconds: int64(5)},
  5586  		LbPolicy:       envoy_config_cluster_v3.Cluster_ROUND_ROBIN,
  5587  		OutlierDetection: &envoy_config_cluster_v3.OutlierDetection{
  5588  			SplitExternalLocalOriginErrors: true,
  5589  		},
  5590  	}
  5591  }
  5592  
  5593  func toEnvoyClusterHTTP2(namespace, name, port string) *envoy_config_cluster_v3.Cluster {
  5594  	return &envoy_config_cluster_v3.Cluster{
  5595  		Name: fmt.Sprintf("%s:%s:%s", namespace, name, port),
  5596  		EdsClusterConfig: &envoy_config_cluster_v3.Cluster_EdsClusterConfig{
  5597  			ServiceName: fmt.Sprintf("%s/%s:%s", namespace, name, port),
  5598  		},
  5599  		TypedExtensionProtocolOptions: map[string]*anypb.Any{
  5600  			"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": toAny(&envoy_upstreams_http_v3.HttpProtocolOptions{
  5601  				CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{
  5602  					IdleTimeout: &durationpb.Duration{Seconds: int64(60)},
  5603  				},
  5604  				UpstreamProtocolOptions: &envoy_upstreams_http_v3.HttpProtocolOptions_ExplicitHttpConfig_{
  5605  					ExplicitHttpConfig: &envoy_upstreams_http_v3.HttpProtocolOptions_ExplicitHttpConfig{
  5606  						ProtocolConfig: &envoy_upstreams_http_v3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{},
  5607  					},
  5608  				},
  5609  			}),
  5610  		},
  5611  		ClusterDiscoveryType: &envoy_config_cluster_v3.Cluster_Type{
  5612  			Type: envoy_config_cluster_v3.Cluster_EDS,
  5613  		},
  5614  		ConnectTimeout: &durationpb.Duration{Seconds: int64(5)},
  5615  		LbPolicy:       envoy_config_cluster_v3.Cluster_ROUND_ROBIN,
  5616  		OutlierDetection: &envoy_config_cluster_v3.OutlierDetection{
  5617  			SplitExternalLocalOriginErrors: true,
  5618  		},
  5619  	}
  5620  }
  5621  
  5622  func toRouteAction(namespace, name, port string) *envoy_config_route_v3.Route_Route {
  5623  	return &envoy_config_route_v3.Route_Route{
  5624  		Route: &envoy_config_route_v3.RouteAction{
  5625  			ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
  5626  				Cluster: fmt.Sprintf("%s:%s:%s", namespace, name, port),
  5627  			},
  5628  			MaxStreamDuration: &envoy_config_route_v3.RouteAction_MaxStreamDuration{
  5629  				MaxStreamDuration: &durationpb.Duration{Seconds: 0},
  5630  			},
  5631  		},
  5632  	}
  5633  }
  5634  
  5635  func toListenerFilter(routeName string) *envoy_config_listener.Filter {
  5636  	return &envoy_config_listener.Filter{
  5637  		Name: "envoy.filters.network.http_connection_manager",
  5638  		ConfigType: &envoy_config_listener.Filter_TypedConfig{
  5639  			TypedConfig: toAny(&http_connection_manager_v3.HttpConnectionManager{
  5640  				StatPrefix: routeName,
  5641  				RouteSpecifier: &http_connection_manager_v3.HttpConnectionManager_Rds{
  5642  					Rds: &http_connection_manager_v3.Rds{RouteConfigName: routeName},
  5643  				},
  5644  				UpgradeConfigs: []*http_connection_manager_v3.HttpConnectionManager_UpgradeConfig{
  5645  					{UpgradeType: "websocket"},
  5646  				},
  5647  				UseRemoteAddress: &wrapperspb.BoolValue{Value: true},
  5648  				SkipXffAppend:    false,
  5649  				HttpFilters: []*http_connection_manager_v3.HttpFilter{
  5650  					{
  5651  						Name: "envoy.filters.http.grpc_web",
  5652  						ConfigType: &http_connection_manager_v3.HttpFilter_TypedConfig{
  5653  							TypedConfig: toAny(&grpc_web_v3.GrpcWeb{}),
  5654  						},
  5655  					},
  5656  					{
  5657  						Name: "envoy.filters.http.grpc_stats",
  5658  						ConfigType: &http_connection_manager_v3.HttpFilter_TypedConfig{
  5659  							TypedConfig: toAny(&grpc_stats_v3.FilterConfig{
  5660  								EmitFilterState:     true,
  5661  								EnableUpstreamStats: true,
  5662  							}),
  5663  						},
  5664  					},
  5665  					{
  5666  						Name: "envoy.filters.http.router",
  5667  						ConfigType: &http_connection_manager_v3.HttpFilter_TypedConfig{
  5668  							TypedConfig: toAny(&envoy_extensions_filters_http_router_v3.Router{}),
  5669  						},
  5670  					},
  5671  				},
  5672  				CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{
  5673  					MaxStreamDuration: &durationpb.Duration{
  5674  						Seconds: 0,
  5675  					},
  5676  				},
  5677  			}),
  5678  		},
  5679  	}
  5680  }
  5681  
  5682  func toSocketOptions() []*envoy_config_core_v3.SocketOption {
  5683  	return []*envoy_config_core_v3.SocketOption{
  5684  		{
  5685  			Description: "Enable TCP keep-alive (default to enabled)",
  5686  			Level:       syscall.SOL_SOCKET,
  5687  			Name:        syscall.SO_KEEPALIVE,
  5688  			Value: &envoy_config_core_v3.SocketOption_IntValue{
  5689  				IntValue: 1,
  5690  			},
  5691  			State: envoy_config_core_v3.SocketOption_STATE_PREBIND,
  5692  		},
  5693  		{
  5694  			Description: "TCP keep-alive idle time (in seconds) (defaults to 10s)",
  5695  			Level:       syscall.IPPROTO_TCP,
  5696  			Name:        syscall.TCP_KEEPIDLE,
  5697  			Value: &envoy_config_core_v3.SocketOption_IntValue{
  5698  				IntValue: 10,
  5699  			},
  5700  			State: envoy_config_core_v3.SocketOption_STATE_PREBIND,
  5701  		},
  5702  		{
  5703  			Description: "TCP keep-alive probe intervals (in seconds) (defaults to 5s)",
  5704  			Level:       syscall.IPPROTO_TCP,
  5705  			Name:        syscall.TCP_KEEPINTVL,
  5706  			Value: &envoy_config_core_v3.SocketOption_IntValue{
  5707  				IntValue: 5,
  5708  			},
  5709  			State: envoy_config_core_v3.SocketOption_STATE_PREBIND,
  5710  		},
  5711  		{
  5712  			Description: "TCP keep-alive probe max failures.",
  5713  			Level:       syscall.IPPROTO_TCP,
  5714  			Name:        syscall.TCP_KEEPCNT,
  5715  			Value: &envoy_config_core_v3.SocketOption_IntValue{
  5716  				IntValue: 10,
  5717  			},
  5718  			State: envoy_config_core_v3.SocketOption_STATE_PREBIND,
  5719  		},
  5720  	}
  5721  }
  5722  
  5723  func toAny(message proto.Message) *anypb.Any {
  5724  	a, err := anypb.New(message)
  5725  	if err != nil {
  5726  		return nil
  5727  	}
  5728  	return a
  5729  }