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 }