diff --git a/api/v1alpha1/backend_types.go b/api/v1alpha1/backend_types.go
index a35cd62b6e6..9e28a341ce1 100644
--- a/api/v1alpha1/backend_types.go
+++ b/api/v1alpha1/backend_types.go
@@ -17,7 +17,6 @@ const (
// AppProtocolType defines various backend applications protocols supported by Envoy Gateway
//
// +kubebuilder:validation:Enum=gateway.envoyproxy.io/h2c;gateway.envoyproxy.io/ws;gateway.envoyproxy.io/wss
-// +notImplementedHide
type AppProtocolType string
const (
@@ -37,7 +36,6 @@ const (
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Accepted")].reason`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
-// +notImplementedHide
type Backend struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -49,22 +47,21 @@ type Backend struct {
Status BackendStatus `json:"status,omitempty"`
}
-// BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IPv4 address or unix domain socket
+// BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IP address or unix domain socket
// corresponding to Envoy's Address: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-address
//
-// +kubebuilder:validation:XValidation:rule="(has(self.fqdn) || has(self.ipv4) || has(self.unix))",message="one of fqdn, ipv4 or unix must be specified"
-// +kubebuilder:validation:XValidation:rule="((has(self.fqdn) && !(has(self.ipv4) || has(self.unix))) || (has(self.ipv4) && !(has(self.fqdn) || has(self.unix))) || (has(self.unix) && !(has(self.ipv4) || has(self.fqdn))))",message="only one of fqdn, ipv4 or unix can be specified"
-// +notImplementedHide
+// +kubebuilder:validation:XValidation:rule="(has(self.fqdn) || has(self.ip) || has(self.unix))",message="one of fqdn, ip or unix must be specified"
+// +kubebuilder:validation:XValidation:rule="((has(self.fqdn) && !(has(self.ip) || has(self.unix))) || (has(self.ip) && !(has(self.fqdn) || has(self.unix))) || (has(self.unix) && !(has(self.ip) || has(self.fqdn))))",message="only one of fqdn, ip or unix can be specified"
type BackendEndpoint struct {
// FQDN defines a FQDN endpoint
//
// +optional
FQDN *FQDNEndpoint `json:"fqdn,omitempty"`
- // IPv4 defines an IPv4 endpoint
+ // IP defines an IP endpoint. Currently, only IPv4 Addresses are supported.
//
// +optional
- IPv4 *IPv4Endpoint `json:"ipv4,omitempty"`
+ IP *IPEndpoint `json:"ip,omitempty"`
// Unix defines the unix domain socket endpoint
//
@@ -72,12 +69,10 @@ type BackendEndpoint struct {
Unix *UnixSocket `json:"unix,omitempty"`
}
-// IPv4Endpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
+// IPEndpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-socketaddress
-//
-// +notImplementedHide
-type IPv4Endpoint struct {
- // Address defines the IPv4 address of the backend endpoint.
+type IPEndpoint struct {
+ // Address defines the IP address of the backend endpoint.
//
// +kubebuilder:validation:MinLength=7
// +kubebuilder:validation:MaxLength=15
@@ -93,14 +88,12 @@ type IPv4Endpoint struct {
// FQDNEndpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-socketaddress
-//
-// +notImplementedHide
type FQDNEndpoint struct {
// Hostname defines the FQDN hostname of the backend endpoint.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
- // +kubebuilder:validation:Pattern=`^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
+ // +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$`
Hostname string `json:"hostname"`
// Port defines the port of the backend endpoint.
@@ -112,16 +105,12 @@ type FQDNEndpoint struct {
// UnixSocket describes TCP/UDP unix domain socket address, corresponding to Envoy's Pipe
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-pipe
-//
-// +notImplementedHide
type UnixSocket struct {
// Path defines the unix domain socket path of the backend endpoint.
Path string `json:"path"`
}
// BackendSpec describes the desired state of BackendSpec.
-//
-// +notImplementedHide
type BackendSpec struct {
// Endpoints defines the endpoints to be used when connecting to the backend.
//
@@ -167,7 +156,6 @@ const (
)
// BackendStatus defines the state of Backend
-// +notImplementedHide
type BackendStatus struct {
// Conditions describe the current conditions of the Backend.
//
@@ -181,7 +169,6 @@ type BackendStatus struct {
// BackendList contains a list of Backend resources.
//
// +kubebuilder:object:root=true
-// +notImplementedHide
type BackendList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go
index d3b7637c437..6e84d07ba7e 100644
--- a/api/v1alpha1/envoygateway_types.go
+++ b/api/v1alpha1/envoygateway_types.go
@@ -493,13 +493,13 @@ type ExtensionService struct {
BackendEndpoint `json:",inline"`
// Host define the extension service hostname.
- // Deprecated: use the appropriate transport attribute instead (FQDN,IPv4,Unix)
+ // Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix)
//
// +optional
Host string `json:"host,omitempty"`
// Port defines the port the extension service is exposed on.
- // Deprecated: use the appropriate transport attribute instead (FQDN,IPv4,Unix)
+ // Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix)
//
// +optional
// +kubebuilder:validation:Minimum=0
diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go
index 85f250c6314..27be5e6318d 100644
--- a/api/v1alpha1/ext_proc_types.go
+++ b/api/v1alpha1/ext_proc_types.go
@@ -51,8 +51,8 @@ type ExtProc struct {
//
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
+ // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="self.all(f, f.kind == 'Service' || f.kind == 'Backend')"
+ // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io')"
BackendRefs []BackendRef `json:"backendRefs"`
// MessageTimeout is the timeout for a response to be returned from the external processor
diff --git a/api/v1alpha1/validation/envoygateway_validate.go b/api/v1alpha1/validation/envoygateway_validate.go
index d4f27633c6f..7851dab4fbe 100644
--- a/api/v1alpha1/validation/envoygateway_validate.go
+++ b/api/v1alpha1/validation/envoygateway_validate.go
@@ -86,12 +86,12 @@ func ValidateEnvoyGateway(eg *v1alpha1.EnvoyGateway) error {
}
switch {
- case eg.ExtensionManager.Service.Host == "" && eg.ExtensionManager.Service.FQDN == nil && eg.ExtensionManager.Service.Unix == nil && eg.ExtensionManager.Service.IPv4 == nil:
+ case eg.ExtensionManager.Service.Host == "" && eg.ExtensionManager.Service.FQDN == nil && eg.ExtensionManager.Service.Unix == nil && eg.ExtensionManager.Service.IP == nil:
return fmt.Errorf("extension service must contain a configured target")
- case eg.ExtensionManager.Service.FQDN != nil && (eg.ExtensionManager.Service.IPv4 != nil || eg.ExtensionManager.Service.Unix != nil || eg.ExtensionManager.Service.Host != ""),
- eg.ExtensionManager.Service.IPv4 != nil && (eg.ExtensionManager.Service.FQDN != nil || eg.ExtensionManager.Service.Unix != nil || eg.ExtensionManager.Service.Host != ""),
- eg.ExtensionManager.Service.Unix != nil && (eg.ExtensionManager.Service.IPv4 != nil || eg.ExtensionManager.Service.FQDN != nil || eg.ExtensionManager.Service.Host != ""):
+ case eg.ExtensionManager.Service.FQDN != nil && (eg.ExtensionManager.Service.IP != nil || eg.ExtensionManager.Service.Unix != nil || eg.ExtensionManager.Service.Host != ""),
+ eg.ExtensionManager.Service.IP != nil && (eg.ExtensionManager.Service.FQDN != nil || eg.ExtensionManager.Service.Unix != nil || eg.ExtensionManager.Service.Host != ""),
+ eg.ExtensionManager.Service.Unix != nil && (eg.ExtensionManager.Service.IP != nil || eg.ExtensionManager.Service.FQDN != nil || eg.ExtensionManager.Service.Host != ""):
return fmt.Errorf("only one backend target can be configured for the extension manager")
diff --git a/api/v1alpha1/validation/envoygateway_validate_test.go b/api/v1alpha1/validation/envoygateway_validate_test.go
index 2823e70a47c..4163ff80f80 100644
--- a/api/v1alpha1/validation/envoygateway_validate_test.go
+++ b/api/v1alpha1/validation/envoygateway_validate_test.go
@@ -619,7 +619,7 @@ func TestValidateEnvoyGateway(t *testing.T) {
Hostname: "foo.example.com",
Port: 8080,
},
- IPv4: &v1alpha1.IPv4Endpoint{
+ IP: &v1alpha1.IPEndpoint{
Address: "10.9.8.7",
Port: 8080,
},
diff --git a/api/v1alpha1/validation/envoyproxy_validate.go b/api/v1alpha1/validation/envoyproxy_validate.go
index 9c8eee5731a..c33c8832bb0 100644
--- a/api/v1alpha1/validation/envoyproxy_validate.go
+++ b/api/v1alpha1/validation/envoyproxy_validate.go
@@ -130,7 +130,7 @@ func validateService(spec *egv1a1.EnvoyProxySpec) []error {
for _, serviceLoadBalancerSourceRange := range serviceLoadBalancerSourceRanges {
if ip, _, err := net.ParseCIDR(serviceLoadBalancerSourceRange); err != nil || ip.To4() == nil {
- errs = append(errs, fmt.Errorf("loadBalancerSourceRange:%s is an invalid IPv4 subnet", serviceLoadBalancerSourceRange))
+ errs = append(errs, fmt.Errorf("loadBalancerSourceRange:%s is an invalid IP subnet", serviceLoadBalancerSourceRange))
}
}
}
@@ -140,7 +140,7 @@ func validateService(spec *egv1a1.EnvoyProxySpec) []error {
}
if ip, err := netip.ParseAddr(*serviceLoadBalancerIP); err != nil || !ip.Unmap().Is4() {
- errs = append(errs, fmt.Errorf("loadBalancerIP:%s is an invalid IPv4 address", *serviceLoadBalancerIP))
+ errs = append(errs, fmt.Errorf("loadBalancerIP:%s is an invalid IP address", *serviceLoadBalancerIP))
}
}
if patch := spec.Provider.Kubernetes.EnvoyService.Patch; patch != nil {
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 77a4b2c8b1f..b32ee512bd5 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -259,9 +259,9 @@ func (in *BackendEndpoint) DeepCopyInto(out *BackendEndpoint) {
*out = new(FQDNEndpoint)
**out = **in
}
- if in.IPv4 != nil {
- in, out := &in.IPv4, &out.IPv4
- *out = new(IPv4Endpoint)
+ if in.IP != nil {
+ in, out := &in.IP, &out.IP
+ *out = new(IPEndpoint)
**out = **in
}
if in.Unix != nil {
@@ -2647,16 +2647,16 @@ func (in *HealthCheck) DeepCopy() *HealthCheck {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *IPv4Endpoint) DeepCopyInto(out *IPv4Endpoint) {
+func (in *IPEndpoint) DeepCopyInto(out *IPEndpoint) {
*out = *in
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPv4Endpoint.
-func (in *IPv4Endpoint) DeepCopy() *IPv4Endpoint {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPEndpoint.
+func (in *IPEndpoint) DeepCopy() *IPEndpoint {
if in == nil {
return nil
}
- out := new(IPv4Endpoint)
+ out := new(IPEndpoint)
in.DeepCopyInto(out)
return out
}
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
index cb3538d9874..8e83322e140 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
@@ -69,7 +69,7 @@ spec:
to the backend.
items:
description: |-
- BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IPv4 address or unix domain socket
+ BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IP address or unix domain socket
corresponding to Envoy's Address: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-address
properties:
fqdn:
@@ -80,7 +80,7 @@ spec:
endpoint.
maxLength: 253
minLength: 1
- pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$
type: string
port:
description: Port defines the port of the backend endpoint.
@@ -92,11 +92,12 @@ spec:
- hostname
- port
type: object
- ipv4:
- description: IPv4 defines an IPv4 endpoint
+ ip:
+ description: IP defines an IP endpoint. Currently, only IPv4
+ Addresses are supported.
properties:
address:
- description: Address defines the IPv4 address of the backend
+ description: Address defines the IP address of the backend
endpoint.
maxLength: 15
minLength: 7
@@ -124,12 +125,12 @@ spec:
type: object
type: object
x-kubernetes-validations:
- - message: one of fqdn, ipv4 or unix must be specified
- rule: (has(self.fqdn) || has(self.ipv4) || has(self.unix))
- - message: only one of fqdn, ipv4 or unix can be specified
- rule: ((has(self.fqdn) && !(has(self.ipv4) || has(self.unix)))
- || (has(self.ipv4) && !(has(self.fqdn) || has(self.unix))) ||
- (has(self.unix) && !(has(self.ipv4) || has(self.fqdn))))
+ - message: one of fqdn, ip or unix must be specified
+ rule: (has(self.fqdn) || has(self.ip) || has(self.unix))
+ - message: only one of fqdn, ip or unix can be specified
+ rule: ((has(self.fqdn) && !(has(self.ip) || has(self.unix))) ||
+ (has(self.ip) && !(has(self.fqdn) || has(self.unix))) || (has(self.unix)
+ && !(has(self.ip) || has(self.fqdn))))
maxItems: 4
minItems: 1
type: array
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
index 7f13dee07cd..041a0d9022f 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
@@ -138,10 +138,11 @@ spec:
minItems: 1
type: array
x-kubernetes-validations:
- - message: BackendRefs only supports Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ - message: BackendRefs only supports Service and Backend kind.
+ rule: self.all(f, f.kind == 'Service' || f.kind == 'Backend')
+ - message: BackendRefs only supports Core and gateway.envoyproxy.io
+ group.
+ rule: self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io')
failOpen:
description: |-
FailOpen defines if requests or responses that cannot be processed due to connectivity to the
diff --git a/charts/gateway-helm/templates/_rbac.tpl b/charts/gateway-helm/templates/_rbac.tpl
index 4cf4082a4c2..fb9304e7d89 100644
--- a/charts/gateway-helm/templates/_rbac.tpl
+++ b/charts/gateway-helm/templates/_rbac.tpl
@@ -70,6 +70,7 @@ resources:
- backendtrafficpolicies
- securitypolicies
- envoyextensionpolicies
+- backends
verbs:
- get
- list
@@ -85,6 +86,7 @@ resources:
- backendtrafficpolicies/status
- securitypolicies/status
- envoyextensionpolicies/status
+- backends/status
verbs:
- update
{{- end }}
diff --git a/examples/redis/redis.yaml b/examples/redis/redis.yaml
index 1a6d779265d..cee4a37c559 100644
--- a/examples/redis/redis.yaml
+++ b/examples/redis/redis.yaml
@@ -64,6 +64,7 @@ data:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
extensionApis:
enableEnvoyPatchPolicy: true
+ enableBackend: true
rateLimit:
backend:
type: Redis
diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go
index 8975513d7a7..6afb724bc5f 100644
--- a/internal/cmd/egctl/translate.go
+++ b/internal/cmd/egctl/translate.go
@@ -282,6 +282,7 @@ func translateGatewayAPIToIR(resources *gatewayapi.Resources) (*gatewayapi.Trans
GlobalRateLimitEnabled: true,
EndpointRoutingDisabled: true,
EnvoyPatchPolicyEnabled: true,
+ BackendEnabled: true,
}
// Fix the services in the resources section so that they have an IP address - this prevents nasty
@@ -309,6 +310,7 @@ func translateGatewayAPIToGatewayAPI(resources *gatewayapi.Resources) (gatewayap
GlobalRateLimitEnabled: true,
EndpointRoutingDisabled: true,
EnvoyPatchPolicyEnabled: true,
+ BackendEnabled: true,
}
gRes, _ := gTranslator.Translate(resources)
// Update the status of the GatewayClass based on EnvoyProxy validation
@@ -341,6 +343,7 @@ func translateGatewayAPIToXds(dnsDomain string, resourceType string, resources *
GlobalRateLimitEnabled: true,
EndpointRoutingDisabled: true,
EnvoyPatchPolicyEnabled: true,
+ BackendEnabled: true,
}
gRes, _ := gTranslator.Translate(resources)
diff --git a/internal/extension/registry/extension_manager.go b/internal/extension/registry/extension_manager.go
index c6e251d67c8..f3312923400 100644
--- a/internal/extension/registry/extension_manager.go
+++ b/internal/extension/registry/extension_manager.go
@@ -124,8 +124,8 @@ func getExtensionServerAddress(service *v1alpha1.ExtensionService) string {
switch {
case service.FQDN != nil:
serverAddr = fmt.Sprintf("%s:%d", service.FQDN.Hostname, service.FQDN.Port)
- case service.IPv4 != nil:
- serverAddr = fmt.Sprintf("%s:%d", service.IPv4.Address, service.IPv4.Port)
+ case service.IP != nil:
+ serverAddr = fmt.Sprintf("%s:%d", service.IP.Address, service.IP.Port)
case service.Unix != nil:
serverAddr = fmt.Sprintf("unix://%s", service.Unix.Path)
case service.Host != "":
diff --git a/internal/extension/registry/extension_manager_test.go b/internal/extension/registry/extension_manager_test.go
index 28e7d84ffdd..38386add268 100644
--- a/internal/extension/registry/extension_manager_test.go
+++ b/internal/extension/registry/extension_manager_test.go
@@ -32,10 +32,10 @@ func TestGetExtensionServerAddress(t *testing.T) {
Expected: "extserver.svc.cluster.local:5050",
},
{
- Name: "has an IPv4",
+ Name: "has an IP",
Service: &v1alpha1.ExtensionService{
BackendEndpoint: v1alpha1.BackendEndpoint{
- IPv4: &v1alpha1.IPv4Endpoint{
+ IP: &v1alpha1.IPEndpoint{
Address: "10.10.10.10",
Port: 5050,
},
diff --git a/internal/gatewayapi/backend.go b/internal/gatewayapi/backend.go
new file mode 100644
index 00000000000..8c9f20f69d5
--- /dev/null
+++ b/internal/gatewayapi/backend.go
@@ -0,0 +1,72 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package gatewayapi
+
+import (
+ "fmt"
+ "net/netip"
+ "strings"
+
+ "k8s.io/apimachinery/pkg/util/validation"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/status"
+)
+
+func (t *Translator) ProcessBackends(backends []*egv1a1.Backend) []*egv1a1.Backend {
+ var res []*egv1a1.Backend
+ for _, backend := range backends {
+ backend := backend.DeepCopy()
+
+ // Ensure Backends are enabled
+ if !t.BackendEnabled {
+ status.UpdateBackendStatusAcceptedCondition(backend, false,
+ "The Backend was not accepted since Backend is not enabled in Envoy Gateway Config")
+ } else {
+ if err := validateBackend(backend); err != nil {
+ status.UpdateBackendStatusAcceptedCondition(backend, false, fmt.Sprintf("The Backend was not accepted: %s", err.Error()))
+ } else {
+ status.UpdateBackendStatusAcceptedCondition(backend, true, "The Backend was accepted")
+ }
+ }
+
+ res = append(res, backend)
+ }
+
+ return res
+}
+
+func validateBackend(backend *egv1a1.Backend) error {
+ for _, ep := range backend.Spec.Endpoints {
+ if ep.FQDN != nil {
+ hostname := ep.FQDN.Hostname
+ // must be a valid hostname
+ if errs := validation.IsDNS1123Subdomain(hostname); errs != nil {
+ return fmt.Errorf("hostname %s is not a valid FQDN", hostname)
+ }
+ if len(strings.Split(hostname, ".")) < 2 {
+ return fmt.Errorf("hostname %s should be a domain with at least two segments separated by dots", hostname)
+ }
+ // IP addresses are not allowed so parsing the hostname as an address needs to fail
+ if _, err := netip.ParseAddr(hostname); err == nil {
+ return fmt.Errorf("hostname %s is an IP address", hostname)
+ }
+ } else if ep.IP != nil {
+ ip, err := netip.ParseAddr(ep.IP.Address)
+ if err != nil {
+ return fmt.Errorf("IP address %s is invalid", ep.IP.Address)
+ } else {
+ if !ip.Is4() {
+ return fmt.Errorf("IP address %s is not IPv4", ep.IP.Address)
+ }
+ if ip.IsLoopback() {
+ return fmt.Errorf("IP address %s in the loopback range is not supported", ep.IP.Address)
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go
index b4c89db790f..fc0f67ba2e0 100644
--- a/internal/gatewayapi/envoyextensionpolicy.go
+++ b/internal/gatewayapi/envoyextensionpolicy.go
@@ -439,11 +439,18 @@ func (t *Translator) buildExtProc(
Settings: dsl,
}
- authority = fmt.Sprintf(
- "%s.%s:%d",
- extProc.BackendRefs[0].Name,
- NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace),
- *extProc.BackendRefs[0].Port)
+ if extProc.BackendRefs[0].Port != nil {
+ authority = fmt.Sprintf(
+ "%s.%s:%d",
+ extProc.BackendRefs[0].Name,
+ NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace),
+ *extProc.BackendRefs[0].Port)
+ } else {
+ authority = fmt.Sprintf(
+ "%s.%s",
+ extProc.BackendRefs[0].Name,
+ NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace))
+ }
extProcIR := &ir.ExtProc{
Name: name,
diff --git a/internal/gatewayapi/ext_service.go b/internal/gatewayapi/ext_service.go
index b813aee266b..7e773ac44c9 100644
--- a/internal/gatewayapi/ext_service.go
+++ b/internal/gatewayapi/ext_service.go
@@ -10,11 +10,10 @@ import (
"fmt"
"strings"
- v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
- egv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+ gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
@@ -29,54 +28,42 @@ func (t *Translator) processExtServiceDestination(
resources *Resources,
) (*ir.DestinationSetting, error) {
var (
- endpoints []*ir.DestinationEndpoint
- addrType *ir.DestinationAddressType
- servicePort v1.ServicePort
- backendTLS *ir.TLSUpstreamConfig
+ backendTLS *ir.TLSUpstreamConfig
+ ds *ir.DestinationSetting
)
- serviceNamespace := NamespaceDerefOr(backendRef.Namespace, policyNamespacedName.Namespace)
- service := resources.GetService(serviceNamespace, string(backendRef.Name))
- for _, port := range service.Spec.Ports {
- if port.Port == int32(*backendRef.Port) {
- servicePort = port
- break
- }
- }
+ backendNamespace := NamespaceDerefOr(backendRef.Namespace, policyNamespacedName.Namespace)
- if servicePort.AppProtocol != nil &&
- *servicePort.AppProtocol == "kubernetes.io/h2c" {
- protocol = ir.HTTP2
+ switch KindDerefOr(backendRef.Kind, KindService) {
+ case KindService:
+ ds = t.processServiceDestinationSetting(*backendRef, backendNamespace, protocol, resources)
+ case egv1a1.KindBackend:
+ if !t.BackendEnabled {
+ return nil, fmt.Errorf("resource %s of type Backend cannot be used since Backend is disabled in Envoy Gateway configuration", string(backendRef.Name))
+ }
+ ds = t.processBackendDestinationSetting(*backendRef, backendNamespace, resources)
+ ds.Protocol = protocol
}
- // Route to endpoints by default
- if !t.EndpointRoutingDisabled {
- endpointSlices := resources.GetEndpointSlicesForBackend(
- serviceNamespace, string(backendRef.Name), KindService)
- endpoints, addrType = getIREndpointsFromEndpointSlices(
- endpointSlices, servicePort.Name, servicePort.Protocol)
- } else {
- // Fall back to Service ClusterIP routing
- ep := ir.NewDestEndpoint(
- service.Spec.ClusterIP,
- uint32(*backendRef.Port))
- endpoints = append(endpoints, ep)
+ if ds == nil {
+ return nil, errors.New(
+ "failed to translate external service backendRef")
}
// TODO: support mixed endpointslice address type for the same backendRef
- if !t.EndpointRoutingDisabled && addrType != nil && *addrType == ir.MIXED {
+ if !t.EndpointRoutingDisabled && ds.AddressType != nil && *ds.AddressType == ir.MIXED {
return nil, errors.New(
"mixed endpointslice address type for the same backendRef is not supported")
}
backendTLS = t.applyBackendTLSSetting(
*backendRef,
- serviceNamespace,
+ backendNamespace,
// Gateway is not the appropriate parent reference here because the owner
// of the BackendRef is the policy, and there is no hierarchy
// relationship between the policy and a gateway.
// The owner policy of the BackendRef is used as the parent reference here.
- egv1a2.ParentReference{
+ gwapiv1a2.ParentReference{
Group: ptr.To(gwapiv1.Group(egv1a1.GroupName)),
Kind: ptr.To(gwapiv1.Kind(policyKind)),
Namespace: ptr.To(gwapiv1.Namespace(policyNamespacedName.Namespace)),
@@ -84,13 +71,12 @@ func (t *Translator) processExtServiceDestination(
},
resources)
- return &ir.DestinationSetting{
- Weight: ptr.To(uint32(1)),
- Protocol: protocol,
- Endpoints: endpoints,
- AddressType: addrType,
- TLS: backendTLS,
- }, nil
+ ds.TLS = backendTLS
+
+ // TODO: support weighted non-xRoute backends
+ ds.Weight = ptr.To(uint32(1))
+
+ return ds, nil
}
// TODO: also refer to extension type, as WASM may also introduce destinations
diff --git a/internal/gatewayapi/resource.go b/internal/gatewayapi/resource.go
index d4fe4dde67c..6f03b6267a6 100644
--- a/internal/gatewayapi/resource.go
+++ b/internal/gatewayapi/resource.go
@@ -57,6 +57,7 @@ type Resources struct {
BackendTLSPolicies []*gwapiv1a3.BackendTLSPolicy `json:"backendTLSPolicies,omitempty" yaml:"backendTLSPolicies,omitempty"`
EnvoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy `json:"envoyExtensionPolicies,omitempty" yaml:"envoyExtensionPolicies,omitempty"`
ExtensionServerPolicies []unstructured.Unstructured `json:"extensionServerPolicies,omitempty" yaml:"extensionServerPolicies,omitempty"`
+ Backends []*egv1a1.Backend `json:"backends,omitempty" yaml:"backends,omitempty"`
}
func NewResources() *Resources {
@@ -79,6 +80,7 @@ func NewResources() *Resources {
BackendTLSPolicies: []*gwapiv1a3.BackendTLSPolicy{},
EnvoyExtensionPolicies: []*egv1a1.EnvoyExtensionPolicy{},
ExtensionServerPolicies: []unstructured.Unstructured{},
+ Backends: []*egv1a1.Backend{},
}
}
@@ -112,6 +114,16 @@ func (r *Resources) GetServiceImport(namespace, name string) *mcsapi.ServiceImpo
return nil
}
+func (r *Resources) GetBackend(namespace, name string) *egv1a1.Backend {
+ for _, be := range r.Backends {
+ if be.Namespace == namespace && be.Name == name {
+ return be
+ }
+ }
+
+ return nil
+}
+
func (r *Resources) GetSecret(namespace, name string) *v1.Secret {
for _, secret := range r.Secrets {
if secret.Namespace == namespace && secret.Name == name {
diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go
index 6301193b903..21b0485ef8f 100644
--- a/internal/gatewayapi/route.go
+++ b/internal/gatewayapi/route.go
@@ -7,6 +7,7 @@ package gatewayapi
import (
"fmt"
+ "net"
"strconv"
"strings"
"time"
@@ -19,6 +20,7 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"
+ "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils/regex"
@@ -1191,10 +1193,24 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
},
resources)
ds.Filters = t.processDestinationFilters(routeType, backendRefContext, parentRef, route, resources)
+ case v1alpha1.KindBackend:
+ ds = t.processBackendDestinationSetting(backendRef.BackendObjectReference, backendNamespace, resources)
+ ds.TLS = t.applyBackendTLSSetting(
+ backendRef.BackendObjectReference,
+ backendNamespace,
+ gwapiv1a2.ParentReference{
+ Group: parentRef.Group,
+ Kind: parentRef.Kind,
+ Namespace: parentRef.Namespace,
+ Name: parentRef.Name,
+ SectionName: parentRef.SectionName,
+ Port: parentRef.Port,
+ },
+ resources)
+ ds.Filters = t.processDestinationFilters(routeType, backendRefContext, parentRef, route, resources)
}
- // TODO: support mixed endpointslice address type for the same backendRef
- if !t.EndpointRoutingDisabled && addrType != nil && *addrType == ir.MIXED {
+ if err := validateDestinationSettings(ds, t.EndpointRoutingDisabled, backendRef.Kind); err != nil {
routeStatus := GetRouteStatus(route)
status.SetRouteStatusCondition(routeStatus,
parentRef.routeParentStatusIdx,
@@ -1202,13 +1218,29 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
gwapiv1.RouteConditionResolvedRefs,
metav1.ConditionFalse,
gwapiv1a2.RouteReasonResolvedRefs,
- "Mixed endpointslice address type for the same backendRef is not supported")
+ err.Error())
}
ds.Weight = &weight
return ds
}
+func validateDestinationSettings(destinationSettings *ir.DestinationSetting, endpointRoutingDisabled bool, kind *gwapiv1.Kind) error {
+ // TODO: support mixed endpointslice address type for the same backendRef
+ switch KindDerefOr(kind, KindService) {
+ case v1alpha1.KindBackend:
+ if destinationSettings.AddressType != nil && *destinationSettings.AddressType == ir.MIXED {
+ return fmt.Errorf("mixed FQDN and IP or Unix address type for the same backendRef is not supported")
+ }
+ case KindService, KindServiceImport:
+ if !endpointRoutingDisabled && destinationSettings.AddressType != nil && *destinationSettings.AddressType == ir.MIXED {
+ return fmt.Errorf("mixed endpointslice address type for the same backendRef is not supported")
+ }
+ }
+
+ return nil
+}
+
func (t *Translator) processServiceDestinationSetting(backendRef gwapiv1.BackendObjectReference, backendNamespace string,
protocol ir.AppProtocol, resources *Resources,
) *ir.DestinationSetting {
@@ -1491,3 +1523,66 @@ func getTargetBackendReference(backendRef gwapiv1a2.BackendObjectReference) gwap
}
return ref
}
+
+func (t *Translator) processBackendDestinationSetting(backendRef gwapiv1.BackendObjectReference, backendNamespace string, resources *Resources) *ir.DestinationSetting {
+ var (
+ dstEndpoints []*ir.DestinationEndpoint
+ dstAddrType *ir.DestinationAddressType
+ dstProtocol ir.AppProtocol
+ )
+
+ addrTypeMap := make(map[ir.DestinationAddressType]int)
+
+ backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
+ for _, bep := range backend.Spec.Endpoints {
+ var irde *ir.DestinationEndpoint
+ switch {
+ case bep.IP != nil:
+ ip := net.ParseIP(bep.IP.Address)
+ if ip != nil {
+ addrTypeMap[ir.IP]++
+ irde = &ir.DestinationEndpoint{
+ Host: bep.IP.Address,
+ Port: uint32(bep.IP.Port),
+ }
+ }
+ case bep.FQDN != nil:
+ addrTypeMap[ir.FQDN]++
+ irde = &ir.DestinationEndpoint{
+ Host: bep.FQDN.Hostname,
+ Port: uint32(bep.FQDN.Port),
+ }
+ case bep.Unix != nil:
+ addrTypeMap[ir.IP]++
+ irde = &ir.DestinationEndpoint{
+ Path: ptr.To(bep.Unix.Path),
+ }
+ }
+
+ dstEndpoints = append(dstEndpoints, irde)
+ }
+
+ for addrTypeState, addrTypeCounts := range addrTypeMap {
+ if addrTypeCounts == len(backend.Spec.Endpoints) {
+ dstAddrType = ptr.To(addrTypeState)
+ break
+ }
+ }
+
+ if len(addrTypeMap) > 0 && dstAddrType == nil {
+ dstAddrType = ptr.To(ir.MIXED)
+ }
+
+ for _, ap := range backend.Spec.AppProtocols {
+ if ap == v1alpha1.AppProtocolTypeH2C {
+ dstProtocol = ir.HTTP2
+ break
+ }
+ }
+
+ return &ir.DestinationSetting{
+ Protocol: dstProtocol,
+ Endpoints: dstEndpoints,
+ AddressType: dstAddrType,
+ }
+}
diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go
index f2d407d622e..fa5d3dc11f1 100644
--- a/internal/gatewayapi/runner/runner.go
+++ b/internal/gatewayapi/runner/runner.go
@@ -85,6 +85,7 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
GatewayClassName: v1.ObjectName(resources.GatewayClass.Name),
GlobalRateLimitEnabled: r.EnvoyGateway.RateLimit != nil,
EnvoyPatchPolicyEnabled: r.EnvoyGateway.ExtensionAPIs != nil && r.EnvoyGateway.ExtensionAPIs.EnableEnvoyPatchPolicy,
+ BackendEnabled: r.EnvoyGateway.ExtensionAPIs != nil && r.EnvoyGateway.ExtensionAPIs.EnableBackend,
Namespace: r.Namespace,
MergeGateways: gatewayapi.IsMergeGatewaysEnabled(resources),
}
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index 1bc0d6c622b..0734f7a73cf 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -824,11 +824,7 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso
return nil, errors.New("one of grpc or http must be specified")
}
- if err = t.validateExtServiceBackendReference(
- backendRef,
- policy.Namespace,
- KindSecurityPolicy,
- resources); err != nil {
+ if err = t.validateExtServiceBackendReference(backendRef, policy.Namespace, policy.Kind, resources); err != nil {
return nil, err
}
authority = fmt.Sprintf("%s.%s:%d",
diff --git a/internal/gatewayapi/status/backend.go b/internal/gatewayapi/status/backend.go
new file mode 100644
index 00000000000..7b841baaa8a
--- /dev/null
+++ b/internal/gatewayapi/status/backend.go
@@ -0,0 +1,42 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+// This file contains code derived from Contour,
+// https://github.com/projectcontour/contour
+// from the source file
+// https://github.com/projectcontour/contour/blob/main/internal/status/gatewayclassconditions.go
+// and is provided here subject to the following:
+// Copyright Project Contour Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package status
+
+import (
+ "time"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+)
+
+// UpdateBackendStatusAcceptedCondition updates the status condition for the provided Backend based on the accepted state.
+func UpdateBackendStatusAcceptedCondition(be *egv1a1.Backend, accepted bool, msg string) *egv1a1.Backend {
+ be.Status.Conditions = MergeConditions(be.Status.Conditions, computeBackendAcceptedCondition(be, accepted, msg))
+ return be
+}
+
+// computeBackendAcceptedCondition computes the Backend Accepted status condition.
+func computeBackendAcceptedCondition(be *egv1a1.Backend, accepted bool, msg string) metav1.Condition {
+ switch accepted {
+ case true:
+ return newCondition(string(egv1a1.BackendReasonInvalid), metav1.ConditionTrue,
+ string(egv1a1.BackendConditionAccepted),
+ "The Backend was accepted", time.Now(), be.Generation)
+ default:
+ return newCondition(string(egv1a1.BackendReasonAccepted), metav1.ConditionFalse,
+ string(egv1a1.BackendConditionAccepted),
+ msg, time.Now(), be.Generation)
+ }
+}
diff --git a/internal/gatewayapi/testdata/backend-invalid-feature-disabled.in.yaml b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.in.yaml
new file mode 100644
index 00000000000..af0b2aa9ec5
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.in.yaml
@@ -0,0 +1,61 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/1"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+envoyExtensionPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ namespace: default
+ name: envoy-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extProc:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
diff --git a/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
new file mode 100755
index 00000000000..6b95feb0a07
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
@@ -0,0 +1,178 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was not accepted since Backend is not enabled in Envoy
+ Gateway Config
+ reason: Accepted
+ status: "False"
+ type: Accepted
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ creationTimestamp: null
+ name: envoy-gateway
+ namespace: default
+ spec:
+ extProc:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: 'ExtProcs: resource backend-ip of type Backend cannot be used since
+ Backend is disabled in Envoy Gateway configuration.'
+ reason: Invalid
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ matches:
+ - path:
+ value: /1
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resource default/backend-ip of type Backend cannot be used since
+ Backend is disabled in Envoy Gateway configuration
+ reason: UnsupportedValue
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /1
diff --git a/internal/gatewayapi/testdata/backend-invalid-hostname-address.in.yaml b/internal/gatewayapi/testdata/backend-invalid-hostname-address.in.yaml
new file mode 100644
index 00000000000..81aca19efd8
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-invalid-hostname-address.in.yaml
@@ -0,0 +1,41 @@
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: '*.foo.com'
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: 'localhost'
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: '127.0.0.3'
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: example.com
+ port: 3001
diff --git a/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml b/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
new file mode 100755
index 00000000000..e917d9cb2b8
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
@@ -0,0 +1,77 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: '*.foo.com'
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: 'The Backend was not accepted: hostname *.foo.com is not a valid FQDN'
+ reason: Accepted
+ status: "False"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: localhost
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: 'The Backend was not accepted: hostname localhost should be a domain
+ with at least two segments separated by dots'
+ reason: Accepted
+ status: "False"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 127.0.0.3
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: 'The Backend was not accepted: IP address 127.0.0.3 in the loopback
+ range is not supported'
+ reason: Accepted
+ status: "False"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: example.com
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: 'The Backend was not accepted: IP address example.com is invalid'
+ reason: Accepted
+ status: "False"
+ type: Accepted
+infraIR: {}
+xdsIR: {}
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
index abc821f8eab..a92a6be6023 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
@@ -33,7 +33,10 @@ httpRoutes:
- name: http-backend
namespace: default
port: 8080
-
+ - name: backend-ip-tls
+ namespace: default
+ kind: Backend
+ group: gateway.envoyproxy.io
referenceGrants:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: ReferenceGrant
@@ -54,7 +57,8 @@ referenceGrants:
to:
- group: ""
kind: Service
-
+ - group: gateway.envoyproxy.io
+ kind: Backend
services:
- apiVersion: v1
kind: Service
@@ -133,3 +137,30 @@ backendTLSPolicies:
group: ""
kind: ConfigMap
hostname: example.com
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-backend-ip
+ namespace: default
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: ip-backend
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-tls
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
index 1becf7daff1..71e52ee0b0d 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
@@ -30,6 +30,55 @@ backendTLSPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-backend-ip
+ namespace: default
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: ip-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-tls
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -88,6 +137,10 @@ httpRoutes:
- name: http-backend
namespace: default
port: 8080
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ namespace: default
matches:
- path:
type: Exact
@@ -156,6 +209,16 @@ xdsIR:
name: policy-btls/default-ca
sni: example.com
weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/default-ca
+ sni: ip-backend
+ weight: 1
hostname: '*'
isHTTP2: false
name: httproute/envoy-gateway/httproute-btls/rule/0/match/0/*
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml
index 71ad79e6215..dad20362396 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml
@@ -122,6 +122,8 @@ referenceGrants:
to:
- group: ''
kind: Service
+ - group: gateway.envoyproxy.io
+ kind: Backend
configMaps:
- apiVersion: v1
kind: ConfigMap
@@ -167,6 +169,22 @@ backendTLSPolicies:
group: ''
kind: ConfigMap
hostname: grpc-backend
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: ip-backend
envoyExtensionPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
@@ -185,3 +203,31 @@ envoyExtensionPolicies:
Port: 8000
- Name: grpc-backend-2
Port: 9000
+ - Name: backend-ip
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ - Name: backend-ip-tls
+ Namespace: envoy-gateway
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
index ba95b6a27f0..dcc1e7522b1 100755
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
@@ -31,6 +31,74 @@ backendTLSPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: ip-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
envoyExtensionPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
@@ -46,6 +114,13 @@ envoyExtensionPolicies:
port: 8000
- name: grpc-backend-2
port: 9000
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ namespace: envoy-gateway
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
@@ -243,6 +318,23 @@ xdsIR:
port: 9000
protocol: GRPC
weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
name: envoyextensionpolicy/default/policy-for-http-route/0
hostname: www.foo.com
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/grpcroute-with-backend.in.yaml b/internal/gatewayapi/testdata/grpcroute-with-backend.in.yaml
new file mode 100644
index 00000000000..a02496321ec
--- /dev/null
+++ b/internal/gatewayapi/testdata/grpcroute-with-backend.in.yaml
@@ -0,0 +1,49 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - method:
+ service: com.ExampleExact
+ type: Exact
+ - method:
+ service: com.[A-Z]+
+ type: RegularExpression
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
diff --git a/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
new file mode 100755
index 00000000000..1227e5685d2
--- /dev/null
+++ b/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
@@ -0,0 +1,161 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ matches:
+ - method:
+ service: com.ExampleExact
+ type: Exact
+ - method:
+ service: com.[A-Z]+
+ type: RegularExpression
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resource default/backend-ip of type Backend is not supported for
+ GRPCRoute routes
+ reason: UnsupportedValue
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: true
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: grpcroute/default/grpcroute-1/rule/0
+ settings:
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: true
+ name: grpcroute/default/grpcroute-1/rule/0/match/1/*
+ pathMatch:
+ distinct: false
+ name: ""
+ safeRegex: /com.[A-Z]+/[A-Za-z_][A-Za-z_0-9]*
+ - destination:
+ name: grpcroute/default/grpcroute-1/rule/0
+ settings:
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: true
+ name: grpcroute/default/grpcroute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /com.ExampleExact
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.in.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.in.yaml
new file mode 100644
index 00000000000..d2ecaa7816a
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.in.yaml
@@ -0,0 +1,213 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-static
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/1"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - name: service-ip
+ port: 8080
+ - name: service-import-ip
+ group: multicluster.x-k8s.io
+ kind: ServiceImport
+ port: 8081
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-fqdn
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/2"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ - name: service-fqdn
+ port: 8080
+ - name: service-import-fqdn
+ group: multicluster.x-k8s.io
+ kind: ServiceImport
+ port: 8081
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+services:
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: default
+ name: service-fqdn
+ spec:
+ clusterIP: 1.1.1.1
+ ports:
+ - name: http
+ port: 8080
+ protocol: TCP
+ targetPort: 8080
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: default
+ name: service-ip
+ spec:
+ clusterIP: 2.2.2.2
+ ports:
+ - name: http
+ port: 8080
+ protocol: TCP
+ targetPort: 8080
+serviceImports:
+ - apiVersion: multicluster.x-k8s.io/v1alpha1
+ kind: ServiceImport
+ metadata:
+ namespace: default
+ name: service-import-fqdn
+ spec:
+ ips:
+ - 7.7.7.7
+ ports:
+ - port: 8081
+ name: http
+ protocol: TCP
+ - apiVersion: multicluster.x-k8s.io/v1alpha1
+ kind: ServiceImport
+ metadata:
+ namespace: default
+ name: service-import-ip
+ spec:
+ ips:
+ - 8.8.8.8
+ ports:
+ - port: 8081
+ name: http
+ protocol: TCP
+endpointSlices:
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-service-fqdn
+ namespace: default
+ labels:
+ kubernetes.io/service-name: service-fqdn
+ addressType: FQDN
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8080
+ endpoints:
+ - addresses:
+ - "bar.foo"
+ conditions:
+ ready: true
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-service-ip
+ namespace: default
+ labels:
+ kubernetes.io/service-name: service-ip
+ addressType: IP
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8080
+ endpoints:
+ - addresses:
+ - "4.3.2.1"
+ conditions:
+ ready: true
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: service-import-fqdn
+ namespace: default
+ labels:
+ multicluster.kubernetes.io/service-name: service-import-fqdn
+ addressType: FQDN
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8080
+ endpoints:
+ - addresses:
+ - "foo.bar"
+ conditions:
+ ready: true
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: service-import-ip
+ namespace: default
+ labels:
+ multicluster.kubernetes.io/service-name: service-import-ip
+ addressType: IPv4
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8081
+ endpoints:
+ - addresses:
+ - "1.2.3.4"
+ conditions:
+ ready: true
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
new file mode 100755
index 00000000000..94073d08678
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
@@ -0,0 +1,268 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-static
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - name: service-ip
+ port: 8080
+ - group: multicluster.x-k8s.io
+ kind: ServiceImport
+ name: service-import-ip
+ port: 8081
+ matches:
+ - path:
+ value: /1
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-fqdn
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ - name: service-fqdn
+ port: 8080
+ - group: multicluster.x-k8s.io
+ kind: ServiceImport
+ name: service-import-fqdn
+ port: 8081
+ matches:
+ - path:
+ value: /2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-static/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 4.3.2.1
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.2.3.4
+ port: 8081
+ protocol: HTTP
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-static/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /1
+ - destination:
+ name: httproute/default/httproute-fqdn/rule/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: bar.foo
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: foo.bar
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-fqdn/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /2
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.in.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.in.yaml
new file mode 100644
index 00000000000..340df45fb61
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.in.yaml
@@ -0,0 +1,121 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/1"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-uds-mixed
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/3"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-ip-fqdn
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/2"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-uds-fqdn
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-uds-mixed
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-mixed-ip-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-mixed-ip-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-mixed-uds-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - ip:
+ address: 1.1.1.1
+ port: 3001
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
new file mode 100755
index 00000000000..7c15bd583aa
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
@@ -0,0 +1,318 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-uds-mixed
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-mixed-ip-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-mixed-ip-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-mixed-uds-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 3
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-uds-mixed
+ matches:
+ - path:
+ value: /1
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Unix domain socket found in Backend default/backend-ip-uds-mixed
+ is not supported for xRoute backendRefs
+ reason: UnsupportedRefAddressFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-ip-fqdn
+ matches:
+ - path:
+ value: /3
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: mixed FQDN and IP or Unix address type for the same backendRef is
+ not supported
+ reason: ResolvedRefs
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-uds-fqdn
+ matches:
+ - path:
+ value: /2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: mixed FQDN and IP or Unix address type for the same backendRef is
+ not supported
+ reason: ResolvedRefs
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /1
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: Mixed
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-3/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /3
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: Mixed
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /2
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.in.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.in.yaml
new file mode 100644
index 00000000000..aeccfd4a899
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.in.yaml
@@ -0,0 +1,156 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/1"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/3"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/2"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-4
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/4"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-localhost
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-5
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/5"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn-localhost
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-localhost
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 127.0.0.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn-localhost
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: localhost
+ port: 3001
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
new file mode 100755
index 00000000000..c05c89dc883
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
@@ -0,0 +1,425 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-localhost
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 127.0.0.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: 'The Backend was not accepted: IP address 127.0.0.1 in the loopback
+ range is not supported'
+ reason: Accepted
+ status: "False"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn-localhost
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: localhost
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: 'The Backend was not accepted: hostname localhost should be a domain
+ with at least two segments separated by dots'
+ reason: Accepted
+ status: "False"
+ type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 5
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ matches:
+ - path:
+ value: /1
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Unix domain socket found in Backend default/backend-uds is not supported
+ for xRoute backendRefs
+ reason: UnsupportedRefAddressFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ matches:
+ - path:
+ value: /3
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ matches:
+ - path:
+ value: /2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-4
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-localhost
+ matches:
+ - path:
+ value: /4
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-5
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn-localhost
+ matches:
+ - path:
+ value: /5
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /1
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-3/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /3
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /2
+ - destination:
+ name: httproute/default/httproute-4/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 127.0.0.1
+ port: 3001
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-4/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /4
+ - destination:
+ name: httproute/default/httproute-5/rule/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: localhost
+ port: 3001
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-5/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /5
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.in.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.in.yaml
new file mode 100644
index 00000000000..1acf67d9dfe
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.in.yaml
@@ -0,0 +1,133 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/1"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/2"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/3"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/4"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
new file mode 100644
index 00000000000..ce5b2c2f580
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
@@ -0,0 +1,366 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 4
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ matches:
+ - path:
+ value: /1
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Mixed endpointslice address type between backendRefs is not supported
+ reason: ResolvedRefs
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ matches:
+ - path:
+ value: /2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Unix domain socket found in Backend default/backend-uds is not supported
+ for xRoute backendRefs
+ reason: UnsupportedRefAddressFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ matches:
+ - path:
+ value: /3
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Mixed endpointslice address type between backendRefs is not supported
+ reason: ResolvedRefs
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ matches:
+ - path:
+ value: /4
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Unix domain socket found in Backend default/backend-uds is not supported
+ for xRoute backendRefs
+ reason: UnsupportedRefAddressFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /1
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /2
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-3/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /3
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-3/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /4
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.in.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.in.yaml
new file mode 100644
index 00000000000..671c19d3b2e
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.in.yaml
@@ -0,0 +1,138 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/1"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds2
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/2"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip2
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/3"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn2
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-uds2
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend2.sock
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn2
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary2.foo.com
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip2
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3001
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
new file mode 100755
index 00000000000..ab764497bb2
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
@@ -0,0 +1,356 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-uds
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend.sock
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-uds2
+ namespace: default
+ spec:
+ endpoints:
+ - unix:
+ path: /var/run/backend2.sock
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn2
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary2.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip2
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 3
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-uds2
+ matches:
+ - path:
+ value: /1
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Unix domain socket found in Backend default/backend-uds2 is not supported
+ for xRoute backendRefs
+ reason: UnsupportedRefAddressFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip2
+ matches:
+ - path:
+ value: /2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn2
+ matches:
+ - path:
+ value: /3
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - weight: 1
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /1
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3001
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /2
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary2.foo.com
+ port: 3000
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-3/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /3
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml
index cea76f60b53..314276475f2 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml
@@ -69,7 +69,7 @@ httpRoutes:
status: "True"
type: Accepted
- lastTransitionTime: null
- message: Mixed endpointslice address type for the same backendRef is not supported
+ message: mixed endpointslice address type for the same backendRef is not supported
reason: ResolvedRefs
status: "False"
type: ResolvedRefs
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.in.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.in.yaml
new file mode 100644
index 00000000000..3f4b5483d45
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.in.yaml
@@ -0,0 +1,77 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-ip-uds
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-mixed-ip-uds
+ namespace: default
+ spec:
+ appProtocols:
+ - gateway.envoyproxy.io/h2c
+ endpoints:
+ - ip:
+ address: 10.244.0.28
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ appProtocols:
+ - gateway.envoyproxy.io/h2c
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
new file mode 100755
index 00000000000..430f6e854ab
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
@@ -0,0 +1,225 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-mixed-ip-uds
+ namespace: default
+ spec:
+ appProtocols:
+ - gateway.envoyproxy.io/h2c
+ endpoints:
+ - ip:
+ address: 10.244.0.28
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ appProtocols:
+ - gateway.envoyproxy.io/h2c
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-ip-uds
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 10.244.0.28
+ port: 3000
+ protocol: HTTP2
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: HTTP2
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.in.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.in.yaml
new file mode 100644
index 00000000000..b837c641bb1
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.in.yaml
@@ -0,0 +1,75 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ weight: 1
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-ip-uds
+ weight: 2
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-mixed-ip-uds
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 10.244.0.28
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
new file mode 100755
index 00000000000..bd996c60996
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
@@ -0,0 +1,221 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-mixed-ip-uds
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 10.244.0.28
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ weight: 1
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-mixed-ip-uds
+ weight: 2
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 10.244.0.28
+ port: 3000
+ weight: 2
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ name: httproute/default/httproute-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml
index 1029946b473..7ced70ec612 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml
@@ -70,8 +70,8 @@ httpRoutes:
type: Accepted
- lastTransitionTime: null
message: Group is invalid, only the core API group (specified by omitting
- the group field or setting it to an empty string) and multicluster.x-k8s.io
- are supported
+ the group field or setting it to an empty string), multicluster.x-k8s.io
+ and gateway.envoyproxy.io are supported
reason: InvalidKind
status: "False"
type: ResolvedRefs
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml
index 5deb6eea7f4..26d256a564b 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml
@@ -68,7 +68,8 @@ httpRoutes:
status: "True"
type: Accepted
- lastTransitionTime: null
- message: Kind is invalid, only Service and MCS ServiceImport are supported
+ message: Kind is invalid, only Service, MCS ServiceImport and Envoy Gateway
+ Backend are supported
reason: InvalidKind
status: "False"
type: ResolvedRefs
diff --git a/internal/gatewayapi/testdata/tcproute-with-backend.in.yaml b/internal/gatewayapi/testdata/tcproute-with-backend.in.yaml
new file mode 100644
index 00000000000..667b2a3b938
--- /dev/null
+++ b/internal/gatewayapi/testdata/tcproute-with-backend.in.yaml
@@ -0,0 +1,41 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: tcp
+ protocol: TCP
+ port: 90
+ allowedRoutes:
+ namespaces:
+ from: All
+tcpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: TCPRoute
+ metadata:
+ namespace: default
+ name: tcproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
diff --git a/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml b/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
new file mode 100755
index 00000000000..c82e53e39e0
--- /dev/null
+++ b/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
@@ -0,0 +1,123 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: tcp
+ port: 90
+ protocol: TCP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: tcp
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: TCPRoute
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/tcp
+ ports:
+ - containerPort: 10090
+ name: tcp-90
+ protocol: TCP
+ servicePort: 90
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+tcpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: TCPRoute
+ metadata:
+ creationTimestamp: null
+ name: tcproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resource default/backend-ip of type Backend is not supported for
+ TCPRoute routes
+ reason: UnsupportedValue
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ tcp:
+ - address: 0.0.0.0
+ name: envoy-gateway/gateway-1/tcp
+ port: 10090
+ routes:
+ - destination:
+ name: tcproute/default/tcproute-1/rule/-1
+ settings:
+ - weight: 1
+ name: tcproute/default/tcproute-1
diff --git a/internal/gatewayapi/testdata/tlsroute-with-backend.in.yaml b/internal/gatewayapi/testdata/tlsroute-with-backend.in.yaml
new file mode 100644
index 00000000000..7fb25e34902
--- /dev/null
+++ b/internal/gatewayapi/testdata/tlsroute-with-backend.in.yaml
@@ -0,0 +1,44 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: tls
+ protocol: TLS
+ hostname: foo.com
+ port: 90
+ tls:
+ mode: Passthrough
+ allowedRoutes:
+ namespaces:
+ from: All
+tlsRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: TLSRoute
+ metadata:
+ namespace: default
+ name: tlsroute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
diff --git a/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
new file mode 100755
index 00000000000..f5839c370d4
--- /dev/null
+++ b/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
@@ -0,0 +1,130 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: foo.com
+ name: tls
+ port: 90
+ protocol: TLS
+ tls:
+ mode: Passthrough
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: tls
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: TLSRoute
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/tls
+ ports:
+ - containerPort: 10090
+ name: tls-90
+ protocol: TLS
+ servicePort: 90
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+tlsRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: TLSRoute
+ metadata:
+ creationTimestamp: null
+ name: tlsroute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resource default/backend-ip of type Backend is not supported for
+ TLSRoute routes
+ reason: UnsupportedValue
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ tcp:
+ - address: 0.0.0.0
+ name: envoy-gateway/gateway-1/tls
+ port: 10090
+ routes:
+ - destination:
+ name: tlsroute/default/tlsroute-1/rule/-1
+ settings:
+ - weight: 1
+ name: tlsroute/default/tlsroute-1
+ tls:
+ inspector:
+ snis:
+ - foo.com
diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go
index 6d095daa7c0..08f0dd8a98e 100644
--- a/internal/gatewayapi/translator.go
+++ b/internal/gatewayapi/translator.go
@@ -95,6 +95,9 @@ type Translator struct {
// feature is enabled.
EnvoyPatchPolicyEnabled bool
+ // BackendEnabled when the Backend feature is enabled.
+ BackendEnabled bool
+
// ExtensionGroupKinds stores the group/kind for all resources
// introduced by an Extension so that the translator can
// store referenced resources in the IR for later use.
@@ -122,6 +125,7 @@ func newTranslateResult(gateways []*GatewayContext,
backendTLSPolicies []*gwapiv1a3.BackendTLSPolicy,
envoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy,
extPolicies []unstructured.Unstructured,
+ backends []*egv1a1.Backend,
xdsIR XdsIRMap, infraIR InfraIRMap,
) *TranslateResult {
translateResult := &TranslateResult{
@@ -155,6 +159,7 @@ func newTranslateResult(gateways []*GatewayContext,
translateResult.EnvoyExtensionPolicies = append(translateResult.EnvoyExtensionPolicies, envoyExtensionPolicies...)
translateResult.ExtensionServerPolicies = append(translateResult.ExtensionServerPolicies, extPolicies...)
+ translateResult.Backends = append(translateResult.Backends, backends...)
return translateResult
}
@@ -182,6 +187,9 @@ func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
// Process all Addresses for all relevant Gateways.
t.ProcessAddresses(gateways, xdsIR, infraIR, resources)
+ // process all Backends
+ backends := t.ProcessBackends(resources.Backends)
+
// Process all relevant HTTPRoutes.
httpRoutes := t.ProcessHTTPRoutes(resources.HTTPRoutes, gateways, resources, xdsIR)
@@ -245,7 +253,7 @@ func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
return newTranslateResult(gateways, httpRoutes, grpcRoutes, tlsRoutes,
tcpRoutes, udpRoutes, clientTrafficPolicies, backendTrafficPolicies,
securityPolicies, resources.BackendTLSPolicies, envoyExtensionPolicies,
- extServerPolicies, xdsIR, infraIR), translateErrs
+ extServerPolicies, backends, xdsIR, infraIR), translateErrs
}
// GetRelevantGateways returns GatewayContexts, containing a copy of the original
diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go
index 56f85ad5c8c..617998713e9 100644
--- a/internal/gatewayapi/translator_test.go
+++ b/internal/gatewayapi/translator_test.go
@@ -44,11 +44,16 @@ func TestTranslate(t *testing.T) {
testCasesConfig := []struct {
name string
EnvoyPatchPolicyEnabled bool
+ BackendEnabled bool
}{
{
name: "envoypatchpolicy-invalid-feature-disabled",
EnvoyPatchPolicyEnabled: false,
},
+ {
+ name: "backend-invalid-feature-disabled",
+ EnvoyPatchPolicyEnabled: false,
+ },
}
inputFiles, err := filepath.Glob(filepath.Join("testdata", "*.in.yaml"))
@@ -63,10 +68,12 @@ func TestTranslate(t *testing.T) {
resources := &Resources{}
mustUnmarshal(t, input, resources)
envoyPatchPolicyEnabled := true
+ backendEnabled := true
for _, config := range testCasesConfig {
if config.name == strings.Split(filepath.Base(inputFile), ".")[0] {
envoyPatchPolicyEnabled = config.EnvoyPatchPolicyEnabled
+ backendEnabled = config.BackendEnabled
}
}
@@ -75,6 +82,7 @@ func TestTranslate(t *testing.T) {
GatewayClassName: "envoy-gateway-class",
GlobalRateLimitEnabled: true,
EnvoyPatchPolicyEnabled: envoyPatchPolicyEnabled,
+ BackendEnabled: backendEnabled,
Namespace: "envoy-gateway-system",
MergeGateways: IsMergeGatewaysEnabled(resources),
}
diff --git a/internal/gatewayapi/validate.go b/internal/gatewayapi/validate.go
index 1e57a60b0fb..46847d02ac2 100644
--- a/internal/gatewayapi/validate.go
+++ b/internal/gatewayapi/validate.go
@@ -66,12 +66,16 @@ func (t *Translator) validateBackendRef(backendRefContext BackendRefContext, par
if !t.validateBackendServiceImport(backendRef, parentRef, resources, backendNamespace, route, protocol) {
return false
}
+ case egv1a1.KindBackend:
+ if !t.validateBackendRefBackend(backendRef, parentRef, resources, backendNamespace, route, routeKind) {
+ return false
+ }
}
return true
}
func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool {
- if backendRef.Group != nil && *backendRef.Group != "" && *backendRef.Group != GroupMultiClusterService {
+ if backendRef.Group != nil && *backendRef.Group != "" && *backendRef.Group != GroupMultiClusterService && *backendRef.Group != egv1a1.GroupName {
routeStatus := GetRouteStatus(route)
status.SetRouteStatusCondition(routeStatus,
parentRef.routeParentStatusIdx,
@@ -79,7 +83,7 @@ func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, p
gwapiv1.RouteConditionResolvedRefs,
metav1.ConditionFalse,
gwapiv1.RouteReasonInvalidKind,
- fmt.Sprintf("Group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) and %s are supported", GroupMultiClusterService),
+ fmt.Sprintf("Group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string), %s and %s are supported", GroupMultiClusterService, egv1a1.GroupName),
)
return false
}
@@ -87,7 +91,7 @@ func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, p
}
func (t *Translator) validateBackendRefKind(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool {
- if backendRef.Kind != nil && *backendRef.Kind != KindService && *backendRef.Kind != KindServiceImport {
+ if backendRef.Kind != nil && *backendRef.Kind != KindService && *backendRef.Kind != KindServiceImport && *backendRef.Kind != egv1a1.KindBackend {
routeStatus := GetRouteStatus(route)
status.SetRouteStatusCondition(routeStatus,
parentRef.routeParentStatusIdx,
@@ -95,7 +99,7 @@ func (t *Translator) validateBackendRefKind(backendRef *gwapiv1a2.BackendRef, pa
gwapiv1.RouteConditionResolvedRefs,
metav1.ConditionFalse,
gwapiv1.RouteReasonInvalidKind,
- "Kind is invalid, only Service and MCS ServiceImport are supported",
+ "Kind is invalid, only Service, MCS ServiceImport and Envoy Gateway Backend are supported",
)
return false
}
@@ -173,6 +177,10 @@ func (t *Translator) validateBackendNamespace(backendRef *gwapiv1a2.BackendRef,
}
func (t *Translator) validateBackendPort(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool {
+ // Envoy Gateway Backends do not require a port in the backend ref
+ if backendRef != nil && backendRef.Kind != nil && string(*backendRef.Kind) == egv1a1.KindBackend {
+ return true
+ }
if backendRef.Port == nil {
routeStatus := GetRouteStatus(route)
status.SetRouteStatusCondition(routeStatus,
@@ -260,6 +268,70 @@ func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendR
return true
}
+func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, resources *Resources,
+ backendNamespace string, route RouteContext, kind gwapiv1.Kind,
+) bool {
+ // TODO: support additional route kinds
+ routeStatus := GetRouteStatus(route)
+
+ if !t.BackendEnabled {
+ status.SetRouteStatusCondition(routeStatus,
+ parentRef.routeParentStatusIdx,
+ route.GetGeneration(),
+ gwapiv1.RouteConditionResolvedRefs,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonUnsupportedValue,
+ fmt.Sprintf("Resource %s/%s of type Backend cannot be used since Backend is disabled in Envoy Gateway configuration",
+ NamespaceDerefOr(backendRef.Namespace, route.GetNamespace()), string(backendRef.Name)),
+ )
+ return false
+ }
+
+ if kind != KindHTTPRoute {
+ status.SetRouteStatusCondition(routeStatus,
+ parentRef.routeParentStatusIdx,
+ route.GetGeneration(),
+ gwapiv1.RouteConditionResolvedRefs,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonUnsupportedValue,
+ fmt.Sprintf("Resource %s/%s of type Backend is not supported for %s routes", NamespaceDerefOr(backendRef.Namespace, route.GetNamespace()),
+ string(backendRef.Name), kind),
+ )
+ return false
+ }
+
+ backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
+ if backend == nil {
+ status.SetRouteStatusCondition(routeStatus,
+ parentRef.routeParentStatusIdx,
+ route.GetGeneration(),
+ gwapiv1.RouteConditionResolvedRefs,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonBackendNotFound,
+ fmt.Sprintf("Backend %s/%s not found", NamespaceDerefOr(backendRef.Namespace, route.GetNamespace()),
+ string(backendRef.Name)),
+ )
+ return false
+ }
+
+ for _, bep := range backend.Spec.Endpoints {
+ if bep.Unix != nil {
+ status.SetRouteStatusCondition(routeStatus,
+ parentRef.routeParentStatusIdx,
+ route.GetGeneration(),
+ gwapiv1.RouteConditionResolvedRefs,
+ metav1.ConditionFalse,
+ "UnsupportedRefAddressFound",
+ fmt.Sprintf("Unix domain socket found in Backend %s/%s is not supported for xRoute backendRefs", backendNamespace,
+ string(backendRef.Name)),
+ )
+ return false
+ }
+ }
+
+ return true
+}
+
func (t *Translator) validateListenerConditions(listener *ListenerContext) (isReady bool) {
lConditions := listener.GetConditions()
if len(lConditions) == 0 {
@@ -927,10 +999,10 @@ func (t *Translator) validateSecretObjectRef(
// This can also be used for the other external services deployed in the cluster,
// such as the external processing filter, gRPC Access Log Service, etc.
// It checks:
-// 1. The group is nil or empty, indicating the core API group.
-// 2. The kind is Service.
-// 3. The port is specified.
-// 4. The service exists and the specified port is found.
+// 1. The group is nil or empty, indicating the core API group, or gateway.envoyproxy.io
+// 2. The kind is Service or Backend.
+// 3. The port is specified for Services.
+// 4. The Service or Backend exists and the specified port is found.
// 5. The cross-namespace reference is permitted by the ReferenceGrants if the
// namespace is different from the policy's namespace.
func (t *Translator) validateExtServiceBackendReference(
@@ -941,43 +1013,54 @@ func (t *Translator) validateExtServiceBackendReference(
) error {
// These are sanity checks, they should never happen because the API server
// should have caught them
- if backendRef.Group != nil && *backendRef.Group != "" {
+ if backendRef.Group != nil && *backendRef.Group != "" && *backendRef.Group != egv1a1.GroupName {
return errors.New(
"group is invalid, only the core API group (specified by omitting" +
- " the group field or setting it to an empty string) is supported")
+ " the group field or setting it to an empty string) and the" +
+ " gateway.envoyproxy.io API group are supported")
}
- if backendRef.Kind != nil && *backendRef.Kind != KindService {
+ if backendRef.Kind != nil && *backendRef.Kind != KindService && *backendRef.Kind != egv1a1.KindBackend {
return errors.New("kind is invalid, only Service (specified by omitting " +
- "the kind field or setting it to 'Service') is supported")
+ "the kind field or setting it to 'Service') and Backend are supported")
}
- if backendRef.Port == nil {
+ if backendRef.Port == nil && !(backendRef.Kind != nil && *backendRef.Kind == egv1a1.KindBackend) {
return errors.New("a valid port number corresponding to a port on the Service must be specified")
}
- // check if the service is valid
- serviceNamespace := NamespaceDerefOr(backendRef.Namespace, ownerNamespace)
- service := resources.GetService(serviceNamespace, string(backendRef.Name))
- if service == nil {
- return fmt.Errorf("service %s/%s not found", serviceNamespace, backendRef.Name)
- }
- var portFound bool
- for _, port := range service.Spec.Ports {
- portProtocol := port.Protocol
- if port.Protocol == "" { // Default protocol is TCP
- portProtocol = v1.ProtocolTCP
+ backendRefKind := KindDerefOr(backendRef.Kind, KindService)
+ switch backendRefKind {
+ case KindService:
+ // check if the service is valid
+ serviceNamespace := NamespaceDerefOr(backendRef.Namespace, ownerNamespace)
+ service := resources.GetService(serviceNamespace, string(backendRef.Name))
+ if service == nil {
+ return fmt.Errorf("service %s/%s not found", serviceNamespace, backendRef.Name)
}
- // currently only HTTP and GRPC are supported, both of which are TCP
- if port.Port == int32(*backendRef.Port) && portProtocol == v1.ProtocolTCP {
- portFound = true
- break
+ var portFound bool
+ for _, port := range service.Spec.Ports {
+ portProtocol := port.Protocol
+ if port.Protocol == "" { // Default protocol is TCP
+ portProtocol = v1.ProtocolTCP
+ }
+ // currently only HTTP and GRPC are supported, both of which are TCP
+ if port.Port == int32(*backendRef.Port) && portProtocol == v1.ProtocolTCP {
+ portFound = true
+ break
+ }
}
- }
- if !portFound {
- return fmt.Errorf(
- "TCP Port %d not found on service %s/%s",
- *backendRef.Port, serviceNamespace, string(backendRef.Name),
- )
+ if !portFound {
+ return fmt.Errorf(
+ "TCP Port %d not found on service %s/%s",
+ *backendRef.Port, serviceNamespace, string(backendRef.Name),
+ )
+ }
+ case egv1a1.KindBackend:
+ backendNamespace := NamespaceDerefOr(backendRef.Namespace, ownerNamespace)
+ backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
+ if backend == nil {
+ return fmt.Errorf("backend %s/%s not found", backendNamespace, backendRef.Name)
+ }
}
// check if the cross-namespace reference is permitted
@@ -991,7 +1074,7 @@ func (t *Translator) validateExtServiceBackendReference(
},
crossNamespaceTo{
group: GroupDerefOr(backendRef.Group, ""),
- kind: KindDerefOr(backendRef.Kind, KindService),
+ kind: KindDerefOr(backendRef.Kind, backendRefKind),
namespace: string(*backendRef.Namespace),
name: string(backendRef.Name),
},
@@ -999,7 +1082,7 @@ func (t *Translator) validateExtServiceBackendReference(
) {
return fmt.Errorf(
"backend ref to %s %s/%s not permitted by any ReferenceGrant",
- KindService, *backendRef.Namespace, backendRef.Name)
+ backendRefKind, *backendRef.Namespace, backendRef.Name)
}
}
return nil
diff --git a/internal/gatewayapi/zz_generated.deepcopy.go b/internal/gatewayapi/zz_generated.deepcopy.go
index 358fdaefb38..a5bf8c9974f 100644
--- a/internal/gatewayapi/zz_generated.deepcopy.go
+++ b/internal/gatewayapi/zz_generated.deepcopy.go
@@ -257,6 +257,17 @@ func (in *Resources) DeepCopyInto(out *Resources) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
+ if in.Backends != nil {
+ in, out := &in.Backends, &out.Backends
+ *out = make([]*apiv1alpha1.Backend, len(*in))
+ for i := range *in {
+ if (*in)[i] != nil {
+ in, out := &(*in)[i], &(*out)[i]
+ *out = new(apiv1alpha1.Backend)
+ (*in).DeepCopyInto(*out)
+ }
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources.
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 5253cc17a4b..6fec4597268 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -38,6 +38,8 @@ var (
ErrDestinationNameEmpty = errors.New("field Name must be specified")
ErrDestEndpointHostInvalid = errors.New("field Address must be a valid IP or FQDN address")
ErrDestEndpointPortInvalid = errors.New("field Port specified is invalid")
+ ErrDestEndpointUDSPortInvalid = errors.New("field Port must not be specified for Unix Domain Socket address")
+ ErrDestEndpointUDSHostInvalid = errors.New("field Host must not be specified for Unix Domain Socket address")
ErrStringMatchConditionInvalid = errors.New("only one of the Exact, Prefix, SafeRegex or Distinct fields must be set")
ErrStringMatchNameIsEmpty = errors.New("field Name must be specified")
ErrDirectResponseStatusInvalid = errors.New("only HTTP status codes 100 - 599 are supported for DirectResponse")
@@ -1089,21 +1091,33 @@ type DestinationEndpoint struct {
Host string `json:"host" yaml:"host"`
// Port on the service to forward the request to.
Port uint32 `json:"port" yaml:"port"`
+ // Path refers to the Unix Domain Socket
+ Path *string `json:"path,omitempty" yaml:"path,omitempty"`
}
// Validate the fields within the DestinationEndpoint structure
func (d DestinationEndpoint) Validate() error {
var errs error
- err := validation.IsDNS1123Subdomain(d.Host)
- _, pErr := netip.ParseAddr(d.Host)
+ // unix domain socket
+ if d.Path != nil {
+ if d.Port != 0 {
+ errs = errors.Join(errs, ErrDestEndpointUDSPortInvalid)
+ }
+ if d.Host != "" {
+ errs = errors.Join(errs, ErrDestEndpointUDSHostInvalid)
+ }
+ } else { // IP or FQDN
+ err := validation.IsDNS1123Subdomain(d.Host)
+ _, pErr := netip.ParseAddr(d.Host)
- if err != nil && pErr != nil {
- errs = errors.Join(errs, ErrDestEndpointHostInvalid)
- }
+ if err != nil && pErr != nil {
+ errs = errors.Join(errs, ErrDestEndpointHostInvalid)
+ }
- if d.Port == 0 {
- errs = errors.Join(errs, ErrDestEndpointPortInvalid)
+ if d.Port == 0 {
+ errs = errors.Join(errs, ErrDestEndpointPortInvalid)
+ }
}
return errs
diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go
index 591a89b4889..c760c66055a 100644
--- a/internal/ir/zz_generated.deepcopy.go
+++ b/internal/ir/zz_generated.deepcopy.go
@@ -450,6 +450,11 @@ func (in *ConsistentHash) DeepCopy() *ConsistentHash {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DestinationEndpoint) DeepCopyInto(out *DestinationEndpoint) {
*out = *in
+ if in.Path != nil {
+ in, out := &in.Path, &out.Path
+ *out = new(string)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationEndpoint.
@@ -512,7 +517,7 @@ func (in *DestinationSetting) DeepCopyInto(out *DestinationSetting) {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(DestinationEndpoint)
- **out = **in
+ (*in).DeepCopyInto(*out)
}
}
}
diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go
index 202a5ea1f2e..71f3f2f701f 100644
--- a/internal/provider/kubernetes/controller.go
+++ b/internal/provider/kubernetes/controller.go
@@ -245,6 +245,10 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
}
}
+ if err = r.processBackends(ctx, gwcResource); err != nil {
+ return reconcile.Result{}, err
+ }
+
// Add the referenced services, ServiceImports, and EndpointSlices in
// the collected BackendRefs to the resourceTree.
// BackendRefs are referred by various Route objects and the ExtAuth in SecurityPolicies.
@@ -363,6 +367,7 @@ func (r *gatewayAPIReconciler) managedGatewayClasses(ctx context.Context) ([]*gw
// - Services
// - ServiceImports
// - EndpointSlices
+// - Backends
func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResource *gatewayapi.Resources, resourceMappings *resourceMappings) {
for backendRef := range resourceMappings.allAssociatedBackendRefs {
backendRefKind := gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService)
@@ -398,25 +403,40 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
"name", string(backendRef.Name))
}
endpointSliceLabelKey = mcsapi.LabelServiceName
- }
- // Retrieve the EndpointSlices associated with the service
- endpointSliceList := new(discoveryv1.EndpointSliceList)
- opts := []client.ListOption{
- client.MatchingLabels(map[string]string{
- endpointSliceLabelKey: string(backendRef.Name),
- }),
- client.InNamespace(string(*backendRef.Namespace)),
+ case egv1a1.KindBackend:
+ backend := new(egv1a1.Backend)
+ err := r.client.Get(ctx, types.NamespacedName{Namespace: string(*backendRef.Namespace), Name: string(backendRef.Name)}, backend)
+ if err != nil {
+ r.log.Error(err, "failed to get Backend", "namespace", string(*backendRef.Namespace),
+ "name", string(backendRef.Name))
+ } else {
+ resourceMappings.allAssociatedNamespaces[backend.Namespace] = struct{}{}
+ gwcResource.Backends = append(gwcResource.Backends, backend)
+ r.log.Info("added Backend to resource tree", "namespace", string(*backendRef.Namespace),
+ "name", string(backendRef.Name))
+ }
}
- if err := r.client.List(ctx, endpointSliceList, opts...); err != nil {
- r.log.Error(err, "failed to get EndpointSlices", "namespace", string(*backendRef.Namespace),
- backendRefKind, string(backendRef.Name))
- } else {
- for _, endpointSlice := range endpointSliceList.Items {
- endpointSlice := endpointSlice
- r.log.Info("added EndpointSlice to resource tree", "namespace", endpointSlice.Namespace,
- "name", endpointSlice.Name)
- gwcResource.EndpointSlices = append(gwcResource.EndpointSlices, &endpointSlice)
+
+ // Retrieve the EndpointSlices associated with the Service and ServiceImport
+ if endpointSliceLabelKey != "" {
+ endpointSliceList := new(discoveryv1.EndpointSliceList)
+ opts := []client.ListOption{
+ client.MatchingLabels(map[string]string{
+ endpointSliceLabelKey: string(backendRef.Name),
+ }),
+ client.InNamespace(string(*backendRef.Namespace)),
+ }
+ if err := r.client.List(ctx, endpointSliceList, opts...); err != nil {
+ r.log.Error(err, "failed to get EndpointSlices", "namespace", string(*backendRef.Namespace),
+ backendRefKind, string(backendRef.Name))
+ } else {
+ for _, endpointSlice := range endpointSliceList.Items {
+ endpointSlice := endpointSlice
+ r.log.Info("added EndpointSlice to resource tree", "namespace", endpointSlice.Namespace,
+ "name", endpointSlice.Name)
+ gwcResource.EndpointSlices = append(gwcResource.EndpointSlices, &endpointSlice)
+ }
}
}
}
@@ -946,6 +966,24 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicies(
return nil
}
+// processBackends adds Backends to the resourceTree
+func (r *gatewayAPIReconciler) processBackends(ctx context.Context, resourceTree *gatewayapi.Resources) error {
+ backends := egv1a1.BackendList{}
+ if err := r.client.List(ctx, &backends); err != nil {
+ return fmt.Errorf("error listing Backends: %w", err)
+ }
+
+ for _, backend := range backends.Items {
+ backend := backend
+ // Discard Status to reduce memory consumption in watchable
+ // It will be recomputed by the gateway-api layer
+ backend.Status = egv1a1.BackendStatus{}
+
+ resourceTree.Backends = append(resourceTree.Backends, &backend)
+ }
+ return nil
+}
+
// removeFinalizer removes the gatewayclass finalizer from the provided gc, if it exists.
func (r *gatewayAPIReconciler) removeFinalizer(ctx context.Context, gc *gwapiv1.GatewayClass) error {
if slice.ContainsString(gc.Finalizers, gatewayClassFinalizer) {
@@ -1202,6 +1240,29 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
return err
}
+ // Watch Backend CRUDs and process affected *Route objects.
+ if r.envoyGateway.ExtensionAPIs != nil && r.envoyGateway.ExtensionAPIs.EnableBackend {
+ backendPredicates := []predicate.TypedPredicate[*egv1a1.Backend]{
+ predicate.TypedGenerationChangedPredicate[*egv1a1.Backend]{},
+ predicate.NewTypedPredicateFuncs[*egv1a1.Backend](func(be *egv1a1.Backend) bool {
+ return r.validateBackendForReconcile(be)
+ }),
+ }
+ if r.namespaceLabel != nil {
+ backendPredicates = append(backendPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.Backend](func(be *egv1a1.Backend) bool {
+ return r.hasMatchingNamespaceLabels(be)
+ }))
+ }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &egv1a1.Backend{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, be *egv1a1.Backend) []reconcile.Request {
+ return r.enqueueClass(ctx, be)
+ }),
+ backendPredicates...)); err != nil {
+ return err
+ }
+ }
+
// Watch Node CRUDs to update Gateway Address exposed by Service of type NodePort.
// Node creation/deletion and ExternalIP updates would require update in the Gateway
nPredicates := []predicate.TypedPredicate[*corev1.Node]{
diff --git a/internal/provider/kubernetes/helpers.go b/internal/provider/kubernetes/helpers.go
index d3a1d972a42..a59b7604fb5 100644
--- a/internal/provider/kubernetes/helpers.go
+++ b/internal/provider/kubernetes/helpers.go
@@ -165,11 +165,11 @@ func validateBackendRef(ref *gwapiv1.BackendRef) error {
switch {
case ref == nil:
return nil
- case gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != corev1.GroupName && gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != mcsapi.GroupName:
- return fmt.Errorf("invalid group; must be nil, empty string or %q", mcsapi.GroupName)
- case gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != gatewayapi.KindService && gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != gatewayapi.KindServiceImport:
- return fmt.Errorf("invalid kind %q; must be %q or %q",
- *ref.BackendObjectReference.Kind, gatewayapi.KindService, gatewayapi.KindServiceImport)
+ case gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != corev1.GroupName && gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != mcsapi.GroupName && gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != egv1a1.GroupName:
+ return fmt.Errorf("invalid group; must be nil, empty string %q or %q", mcsapi.GroupName, egv1a1.GroupName)
+ case gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != gatewayapi.KindService && gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != gatewayapi.KindServiceImport && gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != egv1a1.KindBackend:
+ return fmt.Errorf("invalid kind %q; must be %q, %q or %q",
+ *ref.BackendObjectReference.Kind, gatewayapi.KindService, gatewayapi.KindServiceImport, egv1a1.KindBackend)
}
return nil
diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go
index 80426ed1747..b99929196f4 100644
--- a/internal/provider/kubernetes/indexers.go
+++ b/internal/provider/kubernetes/indexers.go
@@ -60,7 +60,7 @@ func addReferenceGrantIndexers(ctx context.Context, mgr manager.Manager) error {
}
// addHTTPRouteIndexers adds indexing on HTTPRoute.
-// - For Service, ServiceImports objects that are referenced in HTTPRoute objects via `.spec.rules.backendRefs`.
+// - For Service, ServiceImports and Backend objects that are referenced in HTTPRoute objects via `.spec.rules.backendRefs`.
// This helps in querying for HTTPRoutes that are affected by a particular Service CRUD.
func addHTTPRouteIndexers(ctx context.Context, mgr manager.Manager) error {
if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1.HTTPRoute{}, gatewayHTTPRouteIndex, gatewayHTTPRouteIndexFunc); err != nil {
@@ -97,7 +97,7 @@ func backendHTTPRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range httproute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService {
+ if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == v1alpha1.KindBackend {
// If an explicit Backend namespace is not provided, use the HTTPRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -264,7 +264,7 @@ func backendGRPCRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range grpcroute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService {
+ if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == v1alpha1.KindBackend {
// If an explicit Backend namespace is not provided, use the GRPCRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -314,7 +314,7 @@ func backendTLSRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range tlsroute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService {
+ if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == v1alpha1.KindBackend {
// If an explicit Backend namespace is not provided, use the TLSRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -364,7 +364,7 @@ func backendTCPRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range tcpRoute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService {
+ if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == v1alpha1.KindBackend {
// If an explicit Backend namespace is not provided, use the TCPRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -416,7 +416,7 @@ func backendUDPRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range udproute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService {
+ if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == v1alpha1.KindBackend {
// If an explicit Backend namespace is not provided, use the UDPRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go
index 97714bd3a40..eb4c35eff74 100644
--- a/internal/provider/kubernetes/predicates.go
+++ b/internal/provider/kubernetes/predicates.go
@@ -288,6 +288,28 @@ func (r *gatewayAPIReconciler) validateServiceForReconcile(obj client.Object) bo
return r.isEnvoyExtensionPolicyReferencingBackend(&nsName)
}
+// validateBackendForReconcile tries finding the owning Gateway of the Backend
+// if it exists, finds the Gateway's Deployment, and further updates the Gateway
+// status Ready condition. All Services are pushed for reconciliation.
+func (r *gatewayAPIReconciler) validateBackendForReconcile(obj client.Object) bool {
+ be, ok := obj.(*egv1a1.Backend)
+ if !ok {
+ r.log.Info("unexpected object type, bypassing reconciliation", "object", obj)
+ return false
+ }
+
+ nsName := utils.NamespacedName(be)
+ if r.isRouteReferencingBackend(&nsName) {
+ return true
+ }
+
+ if r.isSecurityPolicyReferencingBackend(&nsName) {
+ return true
+ }
+
+ return r.isEnvoyExtensionPolicyReferencingBackend(&nsName)
+}
+
func (r *gatewayAPIReconciler) isSecurityPolicyReferencingBackend(nsName *types.NamespacedName) bool {
spList := &egv1a1.SecurityPolicyList{}
if err := r.client.List(context.Background(), spList, &client.ListOptions{
diff --git a/internal/provider/kubernetes/status_updater.go b/internal/provider/kubernetes/status_updater.go
index 1b22a993187..c6bc5d7f11c 100644
--- a/internal/provider/kubernetes/status_updater.go
+++ b/internal/provider/kubernetes/status_updater.go
@@ -285,7 +285,14 @@ func isStatusEqual(objA, objB interface{}) bool {
return true
}
}
+ case *egv1a1.Backend:
+ if b, ok := objB.(*egv1a1.Backend); ok {
+ if cmp.Equal(a.Status, b.Status, opts) {
+ return true
+ }
+ }
}
+
return false
}
@@ -339,6 +346,8 @@ func kindOf(obj interface{}) string {
kind = gatewayapi.KindBackendTLSPolicy
case *unstructured.Unstructured:
kind = o.GetKind()
+ case *egv1a1.Backend:
+ kind = egv1a1.KindBackend
default:
kind = "Unknown"
}
diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go
index a918c159b43..e646f410944 100644
--- a/internal/xds/translator/cluster.go
+++ b/internal/xds/translator/cluster.go
@@ -398,17 +398,7 @@ func buildXdsClusterLoadAssignment(clusterName string, destSettings []*ir.Destin
Metadata: metadata,
HostIdentifier: &endpointv3.LbEndpoint_Endpoint{
Endpoint: &endpointv3.Endpoint{
- Address: &corev3.Address{
- Address: &corev3.Address_SocketAddress{
- SocketAddress: &corev3.SocketAddress{
- Protocol: corev3.SocketAddress_TCP,
- Address: irEp.Host,
- PortSpecifier: &corev3.SocketAddress_PortValue{
- PortValue: irEp.Port,
- },
- },
- },
- },
+ Address: buildAddress(irEp),
},
},
}
@@ -629,6 +619,29 @@ func buildXdsClusterUpstreamOptions(tcpkeepalive *ir.TCPKeepalive) *clusterv3.Up
return ka
}
+func buildAddress(irEp *ir.DestinationEndpoint) *corev3.Address {
+ if irEp.Path != nil {
+ return &corev3.Address{
+ Address: &corev3.Address_Pipe{
+ Pipe: &corev3.Pipe{
+ Path: *irEp.Path,
+ },
+ },
+ }
+ }
+ return &corev3.Address{
+ Address: &corev3.Address_SocketAddress{
+ SocketAddress: &corev3.SocketAddress{
+ Protocol: corev3.SocketAddress_TCP,
+ Address: irEp.Host,
+ PortSpecifier: &corev3.SocketAddress_PortValue{
+ PortValue: irEp.Port,
+ },
+ },
+ },
+ }
+}
+
func buildBackandConnectionBufferLimitBytes(bc *ir.BackendConnection) *wrappers.UInt32Value {
if bc != nil && bc.BufferLimitBytes != nil {
return wrapperspb.UInt32(*bc.BufferLimitBytes)
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-uds-ip.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-uds-ip.yaml
new file mode 100644
index 00000000000..711913d4dfd
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-uds-ip.yaml
@@ -0,0 +1,29 @@
+http:
+- name: "first-listener"
+ address: "0.0.0.0"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.1.1.1"
+ port: 50001
+ weight: 20
+ - endpoints:
+ - host: "2.2.2.2"
+ port: 50002
+ weight: 40
+ - endpoints:
+ - path: "/etc/sock1"
+ weight: 20
+ - endpoints:
+ - path: "/etc/sock2"
+ weight: 20
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.clusters.yaml
new file mode 100644
index 00000000000..d53a7a1b2ce
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.endpoints.yaml
new file mode 100644
index 00000000000..59679c57afe
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.endpoints.yaml
@@ -0,0 +1,40 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.1.1.1
+ portValue: 50001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 20
+ locality:
+ region: first-route-dest/backend/0
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 2.2.2.2
+ portValue: 50002
+ loadBalancingWeight: 1
+ loadBalancingWeight: 40
+ locality:
+ region: first-route-dest/backend/1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ pipe:
+ path: /etc/sock1
+ loadBalancingWeight: 1
+ loadBalancingWeight: 20
+ locality:
+ region: first-route-dest/backend/2
+ - lbEndpoints:
+ - endpoint:
+ address:
+ pipe:
+ path: /etc/sock2
+ loadBalancingWeight: 1
+ loadBalancingWeight: 20
+ locality:
+ region: first-route-dest/backend/3
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.listeners.yaml
new file mode 100644
index 00000000000..67922c7444f
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.listeners.yaml
@@ -0,0 +1,35 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http
+ useRemoteAddress: true
+ name: first-listener
+ drainType: MODIFY_ONLY
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.routes.yaml
new file mode 100644
index 00000000000..0b5b4bee7bb
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.routes.yaml
@@ -0,0 +1,14 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/site/content/en/contributions/design/backend.md b/site/content/en/contributions/design/backend.md
index 32596bffd32..2e3c3a899bc 100644
--- a/site/content/en/contributions/design/backend.md
+++ b/site/content/en/contributions/design/backend.md
@@ -33,7 +33,7 @@ The `Backend` resource is an implementation-specific Gateway-API [BackendObjectR
### Example
Here is an example highlighting how a user can configure a route that forwards traffic to both a K8s Service and a Backend
-that has both unix domain socket and ipv4 endpoints. A [BackendTLSPolicy][] is attached to the backend resource, enabling TLS.
+that has both unix domain socket and ip endpoints. A [BackendTLSPolicy][] is attached to the backend resource, enabling TLS.
```yaml
apiVersion: v1
@@ -58,7 +58,7 @@ spec:
endpoints:
- unix:
path: /var/run/backend.sock
- - ipv4:
+ - ip:
address: 10.244.0.28
port: 3000
---
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index f3683ceee9c..bb2d9f49e54 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -281,7 +281,7 @@ _Appears in:_
-BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IPv4 address or unix domain socket
+BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IP address or unix domain socket
corresponding to Envoy's Address: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-address
_Appears in:_
@@ -291,7 +291,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ipv4` | _[IPv4Endpoint](#ipv4endpoint)_ | false | IPv4 defines an IPv4 endpoint |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
@@ -1533,10 +1533,10 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ipv4` | _[IPv4Endpoint](#ipv4endpoint)_ | false | IPv4 defines an IPv4 endpoint |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
-| `host` | _string_ | false | Host define the extension service hostname.
Deprecated: use the appropriate transport attribute instead (FQDN,IPv4,Unix) |
-| `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: use the appropriate transport attribute instead (FQDN,IPv4,Unix) |
+| `host` | _string_ | false | Host define the extension service hostname.
Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
+| `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
| `tls` | _[ExtensionTLS](#extensiontls)_ | false | TLS defines TLS configuration for communication between Envoy Gateway and
the extension service. |
@@ -1939,11 +1939,11 @@ _Appears in:_
| `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration |
-#### IPv4Endpoint
+#### IPEndpoint
-IPv4Endpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
+IPEndpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-socketaddress
_Appears in:_
@@ -1952,7 +1952,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `address` | _string_ | true | Address defines the IPv4 address of the backend endpoint. |
+| `address` | _string_ | true | Address defines the IP address of the backend endpoint. |
| `port` | _integer_ | true | Port defines the port of the backend endpoint. |
diff --git a/site/content/zh/latest/api/extension_types.md b/site/content/zh/latest/api/extension_types.md
index f3683ceee9c..bb2d9f49e54 100644
--- a/site/content/zh/latest/api/extension_types.md
+++ b/site/content/zh/latest/api/extension_types.md
@@ -281,7 +281,7 @@ _Appears in:_
-BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IPv4 address or unix domain socket
+BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IP address or unix domain socket
corresponding to Envoy's Address: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-address
_Appears in:_
@@ -291,7 +291,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ipv4` | _[IPv4Endpoint](#ipv4endpoint)_ | false | IPv4 defines an IPv4 endpoint |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
@@ -1533,10 +1533,10 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ipv4` | _[IPv4Endpoint](#ipv4endpoint)_ | false | IPv4 defines an IPv4 endpoint |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
-| `host` | _string_ | false | Host define the extension service hostname.
Deprecated: use the appropriate transport attribute instead (FQDN,IPv4,Unix) |
-| `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: use the appropriate transport attribute instead (FQDN,IPv4,Unix) |
+| `host` | _string_ | false | Host define the extension service hostname.
Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
+| `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
| `tls` | _[ExtensionTLS](#extensiontls)_ | false | TLS defines TLS configuration for communication between Envoy Gateway and
the extension service. |
@@ -1939,11 +1939,11 @@ _Appears in:_
| `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration |
-#### IPv4Endpoint
+#### IPEndpoint
-IPv4Endpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
+IPEndpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-socketaddress
_Appears in:_
@@ -1952,7 +1952,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `address` | _string_ | true | Address defines the IPv4 address of the backend endpoint. |
+| `address` | _string_ | true | Address defines the IP address of the backend endpoint. |
| `port` | _integer_ | true | Port defines the port of the backend endpoint. |
diff --git a/test/cel-validation/backend_test.go b/test/cel-validation/backend_test.go
index ab8efd7e629..c78e22ae24c 100644
--- a/test/cel-validation/backend_test.go
+++ b/test/cel-validation/backend_test.go
@@ -48,7 +48,7 @@ func TestBackend(t *testing.T) {
},
},
{
- IPv4: &egv1a1.IPv4Endpoint{
+ IP: &egv1a1.IPEndpoint{
Address: "1.1.1.1",
Port: 443,
},
@@ -106,7 +106,7 @@ func TestBackend(t *testing.T) {
Endpoints: []egv1a1.BackendEndpoint{{}},
}
},
- wantErrors: []string{"spec.endpoints[0]: Invalid value: \"object\": one of fqdn, ipv4 or unix must be specified"},
+ wantErrors: []string{"spec.endpoints[0]: Invalid value: \"object\": one of fqdn, ip or unix must be specified"},
},
{
desc: "Multiple addresses",
@@ -126,7 +126,7 @@ func TestBackend(t *testing.T) {
},
}
},
- wantErrors: []string{"spec.endpoints[0]: Invalid value: \"object\": only one of fqdn, ipv4 or unix can be specified"},
+ wantErrors: []string{"spec.endpoints[0]: Invalid value: \"object\": only one of fqdn, ip or unix can be specified"},
},
{
desc: "Mixed types",
@@ -141,7 +141,7 @@ func TestBackend(t *testing.T) {
},
},
{
- IPv4: &egv1a1.IPv4Endpoint{
+ IP: &egv1a1.IPEndpoint{
Address: "1.1.1.1",
Port: 443,
},
@@ -185,38 +185,38 @@ func TestBackend(t *testing.T) {
}
},
wantErrors: []string{
- "spec.endpoints[0].fqdn.hostname: Invalid value: \"host name\": spec.endpoints[0].fqdn.hostname in body should match '^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'",
- "spec.endpoints[1].fqdn.hostname: Invalid value: \"host_name\": spec.endpoints[1].fqdn.hostname in body should match '^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'",
- "spec.endpoints[2].fqdn.hostname: Invalid value: \"hostname:443\": spec.endpoints[2].fqdn.hostname in body should match '^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'",
- "spec.endpoints[3].fqdn.hostname: Invalid value: \"host.*.name\": spec.endpoints[3].fqdn.hostname in body should match '^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'",
+ "spec.endpoints[0].fqdn.hostname: Invalid value: \"host name\": spec.endpoints[0].fqdn.hostname in body should match '^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$'",
+ "spec.endpoints[1].fqdn.hostname: Invalid value: \"host_name\": spec.endpoints[1].fqdn.hostname in body should match '^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$'",
+ "spec.endpoints[2].fqdn.hostname: Invalid value: \"hostname:443\": spec.endpoints[2].fqdn.hostname in body should match '^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$",
+ "spec.endpoints[3].fqdn.hostname: Invalid value: \"host.*.name\": spec.endpoints[3].fqdn.hostname in body should match '^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$",
},
},
{
- desc: "Invalid IPv4",
+ desc: "Invalid IP",
mutate: func(backend *egv1a1.Backend) {
backend.Spec = egv1a1.BackendSpec{
AppProtocols: []egv1a1.AppProtocolType{egv1a1.AppProtocolTypeH2C},
Endpoints: []egv1a1.BackendEndpoint{
{
- IPv4: &egv1a1.IPv4Endpoint{
+ IP: &egv1a1.IPEndpoint{
Address: "300.0.0.0",
Port: 443,
},
},
{
- IPv4: &egv1a1.IPv4Endpoint{
+ IP: &egv1a1.IPEndpoint{
Address: "0.0.0.0:443",
Port: 443,
},
},
{
- IPv4: &egv1a1.IPv4Endpoint{
+ IP: &egv1a1.IPEndpoint{
Address: "0.0.0.0/12",
Port: 443,
},
},
{
- IPv4: &egv1a1.IPv4Endpoint{
+ IP: &egv1a1.IPEndpoint{
Address: "a.b.c.e",
Port: 443,
},
@@ -225,10 +225,10 @@ func TestBackend(t *testing.T) {
}
},
wantErrors: []string{
- "spec.endpoints[0].ipv4.address: Invalid value: \"300.0.0.0\": spec.endpoints[0].ipv4.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
- "spec.endpoints[1].ipv4.address: Invalid value: \"0.0.0.0:443\": spec.endpoints[1].ipv4.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
- "spec.endpoints[2].ipv4.address: Invalid value: \"0.0.0.0/12\": spec.endpoints[2].ipv4.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
- "spec.endpoints[3].ipv4.address: Invalid value: \"a.b.c.e\": spec.endpoints[3].ipv4.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
+ "spec.endpoints[0].ip.address: Invalid value: \"300.0.0.0\": spec.endpoints[0].ip.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
+ "spec.endpoints[1].ip.address: Invalid value: \"0.0.0.0:443\": spec.endpoints[1].ip.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
+ "spec.endpoints[2].ip.address: Invalid value: \"0.0.0.0/12\": spec.endpoints[2].ip.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
+ "spec.endpoints[3].ip.address: Invalid value: \"a.b.c.e\": spec.endpoints[3].ip.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'",
},
},
}
diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go
index 773ce8640c2..29dab823004 100644
--- a/test/cel-validation/envoyextensionpolicy_test.go
+++ b/test/cel-validation/envoyextensionpolicy_test.go
@@ -208,7 +208,7 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) {
},
}
},
- wantErrors: []string{" spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Core group."},
+ wantErrors: []string{"spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Core and gateway.envoyproxy.io group"},
},
{
desc: "ExtProc with invalid BackendRef Kind",
@@ -236,7 +236,7 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) {
},
}
},
- wantErrors: []string{"spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Service kind."},
+ wantErrors: []string{"spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Service and Backend kind"},
},
{
desc: "ExtProc with invalid fields",
diff --git a/test/config/gatewayclass.yaml b/test/config/gatewayclass.yaml
index 4067b66d58d..e4a801b6b8e 100644
--- a/test/config/gatewayclass.yaml
+++ b/test/config/gatewayclass.yaml
@@ -16,6 +16,20 @@ metadata:
name: proxy-config
namespace: envoy-gateway-system
spec:
+ provider:
+ type: Kubernetes
+ kubernetes:
+ envoyDeployment:
+ container:
+ volumeMounts:
+ - mountPath: /var/run/ext-proc
+ name: socket-dir
+ pod:
+ volumes:
+ - name: socket-dir
+ hostPath:
+ path: /var/run/ext-proc
+ type: ''
telemetry:
metrics:
prometheus: {}
diff --git a/test/e2e/base/manifests.yaml b/test/e2e/base/manifests.yaml
index 5217c46594b..c1e08e63c8b 100644
--- a/test/e2e/base/manifests.yaml
+++ b/test/e2e/base/manifests.yaml
@@ -753,6 +753,108 @@ spec:
from: Same
---
apiVersion: v1
+data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIIDQzCCAiugAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYDVQQKEwpFbnZv
+ eVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBHYXRld2F5
+ IENBMCAXDTI0MDMxMDE1MzIxN1oYDzIxMjQwMzEwMTYzMjE3WjBCMRMwEQYDVQQK
+ EwpFbnZveVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBH
+ YXRld2F5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7ZFmGB4e
+ m1KdGEohAZBfqydAEGLDHJ1YyfHWdd+vBAevdW64bZx3pggJOtgCnePuFd02rDQS
+ dlsJlX/6mFtoQilo6wvxDSJRfaTDbtfTjw+7k8yfd/Jsmh0RWG+UeyI7Na9sXAz7
+ b57mpxsCoNowzeK5ETiOGGNWPcjENJkSnBarz5muN00xIZWBU+yN5PLJNxZvxpZJ
+ Ol/SSI8sno0e0PxAmp3fe7QaXiZj/TAGJPGuTJkUxrHqyZGJtYUxsS8A0dT1zBjj
+ izA5Dp+b5yzYo23Hh7BgpbZ7X4gsDThFuwCD6fHyepuv2zHPqvSsdqg2hAhDp91R
+ zrn7a9GxG2VSIwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
+ AwEB/zAdBgNVHQ4EFgQUUpP1aZ1M2KIuPPWrNPDV2c5CngowDQYJKoZIhvcNAQEL
+ BQADggEBAGSEkAVz+Z0qS4FmA0q4SCpIIq64bsdEjiUzev7pK1LEK0/Y28QBPixV
+ cUXfax18VPR9pls1JgXto9qY+C0hnRZic6611QTJlWK1p6dinQ/eDdYCBC+nv5xx
+ ssASwmplIxMvj3S1qF6dr7sMI2ZVD5HElTWdO19UBLyhiKKZW2KxDsYj+5NRwGFe
+ G+JuDgq7njUM8mdyYk0NehefdBUEUUCQtnwUtW95/429XwqQROuRDteGT9kjD+Y5
+ ea5mW4mfqLeuGJXZs9bdWjKKdLQPrn9IshPysWqz2Hz8dQ1f7N9/g8UWVSjd4cyx
+ S5EAolzVv0yB7wHCWCgfG/ckdOTUNnE=
+ -----END CERTIFICATE-----
+kind: ConfigMap
+metadata:
+ name: backend-tls-checks-certificate
+ namespace: gateway-conformance-infra
+---
+apiVersion: v1
+data:
+ tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURZVENDQWttZ0F3SUJBZ0lSQUpiK2x5QTJqZCtlUmRMTzR4Sm5kWVF3RFFZSktvWklodmNOQVFFTEJRQXcKUWpFVE1CRUdBMVVFQ2hNS1JXNTJiM2xRY205NGVURVFNQTRHQTFVRUN4TUhSMkYwWlhkaGVURVpNQmNHQTFVRQpBeE1RUlc1MmIza2dSMkYwWlhkaGVTQkRRVEFnRncweU5EQXpNVEF4TlRNeU1UZGFHQTh5TVRJME1ETXhNREUyCk16SXhOMW93SkRFUU1BNEdBMVVFQ2hNSFFXTnRaU0JEYnpFUU1BNEdBMVVFQXhNSFpHVm1ZWFZzZERDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtGUnI2cVV1WFN1N3J5bHcvVmZXbm1kM0RXWgpTcGxDUFR6QUh1V3NpOVVrbW5rTVhNOXN3Y1VQZFUyd2NNSHd1bDNpNGJwTlRkUGVWRG04K3JUVXNmaHMySWZuCmhHNW9WV0JnTkJXVEYzRnpiUmgvc3orK3p6MlBnZ0Fpb3NjYmEyVm5qaExyOUM3a0Q3QnRYNVlvSENGQ3lhT24Kem9WNVdNSnBBNHNCeGdOdkpXSU5aRUNnOUlmSWxSMDZMTGlNTXJCRTVRS2cvTG5EUkpuTEZEVFZCTDdzallpVQpZdVZtRWczMXJaOVpsNXViZ09xSU9uU2ROM2RNM1hhUnBCTWFGVXg5UDlQcmhjS3l5NVRkQ3g2MHBIYXMvaFIxCmFjcEp5VmdmRFVDdXNUUFphVFo1eXM0cmhib1l3WDN5cnZKN29lMHM4QmRZU2thT1NBTElDaU9PWGtVQ0F3RUEKQWFOdU1Hd3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUJNQXdHQTFVZApFd0VCL3dRQ01BQXdId1lEVlIwakJCZ3dGb0FVVXBQMWFaMU0yS0l1UFBXck5QRFYyYzVDbmdvd0ZnWURWUjBSCkJBOHdEWUlMWlhoaGJYQnNaUzVqYjIwd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBMkk1MmhrcEwwTXZmejQKeDk3ZjV6dlR5a1VtRWhDSVowN0g0anM0WVg2a1hLWVBzRDBlaGJFbzZUSWgyMkpWMkpyWnRuaWhMQnRGQStuUQp2Zk9QcE1LRnJMUU1DWVozMk9Na045T1pWbmNyMmpQNzNhaE9SaWloaGVBczJYTUtybHZmVWVKTFJrSlBlSVB6CnR2TlVacWExMmZ4T0Jsdy9hV1NqVk9lRDVMVm5nUStrQksydGRoL08xSjFWRGgzdVU3RHNZUThmRm1UcWR6ZzYKUWhtbjhaTXFIS3lNeitOdkt1d1h5eEtyeFZKVEl1QzJXZHhGWlZZMzdtZzJ5Vm9OdFhpSFNQMXpxVWV4SHNEKwpzUDBsZy9jUDdlaitOY3Q5WnpudUZBc2U4cUNDZnlaL2hPQ2NCblZabG1GUFgzRCtJSEpVWUpGaWVkYndsZHljCmw1eG1jaFU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBb1ZHdnFwUzVkSzd1dktYRDlWOWFlWjNjTlpsS21VSTlQTUFlNWF5TDFTU2FlUXhjCnoyekJ4UTkxVGJCd3dmQzZYZUxodWsxTjA5NVVPYno2dE5TeCtHelloK2VFYm1oVllHQTBGWk1YY1hOdEdIK3oKUDc3UFBZK0NBQ0tpeHh0clpXZU9FdXYwTHVRUHNHMWZsaWdjSVVMSm82Zk9oWGxZd21rRGl3SEdBMjhsWWcxawpRS0QwaDhpVkhUb3N1SXd5c0VUbEFxRDh1Y05FbWNzVU5OVUV2dXlOaUpSaTVXWVNEZld0bjFtWG01dUE2b2c2CmRKMDNkMHpkZHBHa0V4b1ZUSDAvMCt1RndyTExsTjBMSHJTa2RxeitGSFZweWtuSldCOE5RSzZ4TTlscE5ubksKeml1RnVoakJmZkt1OG51aDdTendGMWhLUm81SUFzZ0tJNDVlUlFJREFRQUJBb0lCQVFDVGlZUGh2TGVJa2R6aQpSN0RhbnVTK1NiUDJpVVlDdU9RTXhhRDhhVHhTS1hIbHQzckNjak1kcVMrZFovc1lSTFFOM2N5WWVNN3ZNRzFUCmlSUzVnYlZyQVJGZjZrdmlOaVd2U1EwWmxqZGdtVEp6cjRjZWk4STZDUi9hUTlNZnltSUVraHNNRHlSNkpqWjcKSXV6REJkZ0VTM0xpN0R3ak1vSU0rOEl6eGVGMWpTT1ErTjlLcTB3QzMzVzFuOVdIYXZWcWZvcjI0bmVySG9FcwozNmlUMncvdkU1dFJBTFlEbjh6MFp5YUM1d3Nnb3FyTG5UWXlMcnVKWnNGa1NxN25GWEE3cjhXL0dLQjBoL3ZaCmNzYkRlWU1WMjJNckdRTzhYSlAwM3J0cm9DQWJmUUhRd3lEbnpsTFJ3blNGRmhjV0F5UW9qbkozb0RQbzhZaXoKam1meVd5WlpBb0dCQU0vZGtqMGhFZm05SHBBL1dyTGVEb0V5WWtKL3N1R3RyWlpSNS9INnJieHphQ2FlQ3B0UApZQ25JcnBoMjRVYWFvaXFJY0pnazRXRjBmU3RhRnh0SkxSYXpBVElUUFlCZjF0OEEwYkhjN3UxMExiWlZkMG5uCk1lWVJPYlhzQXlvdmxNcm1ZclBPWWFXSEtJL1oyT3NLeC83UkhTcnEwZm1ZcUFYSXpzK2V1Ryt6QW9HQkFNYXMKem9YdlJwVDZGNndYaU5QemFqamc5MHJFMFhZZ0g3VkEvWHJsbUp5MVFRYy8rZzJ1ZXVYMGJ5aVhYY0FMY3BINAoybFlYcEZaelNPRkd6Z01DMEtuQkJyWmxsYWIweUczbWhsWjRtbkFhbmtSUFh4bWpDdmgvZmtkYStlQ1RCMFdHCjBOY3RQSFVvSk9GNWpLNmtxVy9rWVpkWVRPV1FjczNybURFWCtENG5Bb0dCQUwwdkhRenp6MGRyMzZoTGNRSUEKWmxVaUJSb2UzVERYQUhraWZLYllqMDFJQUErOW9VdXZWNGRQOWRBZnluS1hCR2NQbk9Kc0ZwQzdFN3prRnNtbgp0UmpHdkp6VnRCRGxxVXQzbEdKOEFSMHVzdmdUR3ltdytOSTY5VHBrM3BDRGs3bURLMndZdHZpUFpkUmU0alV4CnI4cDBpa1pvUjhrU0xrSnRmQVNzb1pKUEFvR0FWSTk4bjNrR082WnVxT3FqYkVMd2RTRWJZQkdCYlp1aW8wejAKRm5qZWllU0R0d2c5NzlEUnNrcGxmWXRmZGJ2cG1jT25lbms1a3lvaVhPLzhBMEFSZkE4U1FsUGViRjlIWjY5MApnaDEyN2p3R0hPRURneS9vSFhoMlVQeWgyam42SUZlUFQrYUxFdnB4S0I3S0NCTkJvc1E3M1dUUjVldWpVWTN6CkN3SSt3SVVDZ1lFQXJVQ0k4cng3MVd4S3A0dnNObTJpM2JlT3lYa3dVaFhKUmhmL0cwZk5vc2FhT0RvVEdNT1oKVlRRci9hVWJlQ2pWMlZENTEyVkJEQlZnYUNnZ1ZZS3pSMXpJSDFlMXZzVjhQVjN1Snh0Q2FLT3daTHV4OS9HQQp0QzJOKzFTY05GWkxtU3Z0MzU2WG5EL3VwRUcyeVMydmFURDU1K3FVUlVFWk1TWDlPdFpSL2JBPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
+kind: Secret
+metadata:
+ name: backend-tls-checks-certificate
+ namespace: gateway-conformance-infra
+type: kubernetes.io/tls
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: tls-backend-2
+ namespace: gateway-conformance-infra
+spec:
+ selector:
+ app: tls-backend-2
+ ports:
+ - protocol: TCP
+ port: 443
+ targetPort: 8443
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: tls-backend-2
+ namespace: gateway-conformance-infra
+ labels:
+ app: tls-backend-2
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: tls-backend-2
+ template:
+ metadata:
+ labels:
+ app: tls-backend-2
+ spec:
+ containers:
+ - name: tls-backend
+ image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e
+ volumeMounts:
+ - name: secret-volume
+ mountPath: /etc/secret-volume
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: SERVICE_NAME
+ value: tls-backend-2
+ - name: TLS_SERVER_CERT
+ value: /etc/secret-volume/crt
+ - name: TLS_SERVER_PRIVKEY
+ value: /etc/secret-volume/key
+ resources:
+ requests:
+ cpu: 10m
+ volumes:
+ - name: secret-volume
+ secret:
+ secretName: backend-tls-checks-certificate
+ items:
+ - key: tls.crt
+ path: crt
+ - key: tls.key
+ path: key
+---
+apiVersion: v1
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURZVENDQWttZ0F3SUJBZ0lSQUpiK2x5QTJqZCtlUmRMTzR4Sm5kWVF3RFFZSktvWklodmNOQVFFTEJRQXcKUWpFVE1CRUdBMVVFQ2hNS1JXNTJiM2xRY205NGVURVFNQTRHQTFVRUN4TUhSMkYwWlhkaGVURVpNQmNHQTFVRQpBeE1RUlc1MmIza2dSMkYwWlhkaGVTQkRRVEFnRncweU5EQXpNVEF4TlRNeU1UZGFHQTh5TVRJME1ETXhNREUyCk16SXhOMW93SkRFUU1BNEdBMVVFQ2hNSFFXTnRaU0JEYnpFUU1BNEdBMVVFQXhNSFpHVm1ZWFZzZERDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtGUnI2cVV1WFN1N3J5bHcvVmZXbm1kM0RXWgpTcGxDUFR6QUh1V3NpOVVrbW5rTVhNOXN3Y1VQZFUyd2NNSHd1bDNpNGJwTlRkUGVWRG04K3JUVXNmaHMySWZuCmhHNW9WV0JnTkJXVEYzRnpiUmgvc3orK3p6MlBnZ0Fpb3NjYmEyVm5qaExyOUM3a0Q3QnRYNVlvSENGQ3lhT24Kem9WNVdNSnBBNHNCeGdOdkpXSU5aRUNnOUlmSWxSMDZMTGlNTXJCRTVRS2cvTG5EUkpuTEZEVFZCTDdzallpVQpZdVZtRWczMXJaOVpsNXViZ09xSU9uU2ROM2RNM1hhUnBCTWFGVXg5UDlQcmhjS3l5NVRkQ3g2MHBIYXMvaFIxCmFjcEp5VmdmRFVDdXNUUFphVFo1eXM0cmhib1l3WDN5cnZKN29lMHM4QmRZU2thT1NBTElDaU9PWGtVQ0F3RUEKQWFOdU1Hd3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUJNQXdHQTFVZApFd0VCL3dRQ01BQXdId1lEVlIwakJCZ3dGb0FVVXBQMWFaMU0yS0l1UFBXck5QRFYyYzVDbmdvd0ZnWURWUjBSCkJBOHdEWUlMWlhoaGJYQnNaUzVqYjIwd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBMkk1MmhrcEwwTXZmejQKeDk3ZjV6dlR5a1VtRWhDSVowN0g0anM0WVg2a1hLWVBzRDBlaGJFbzZUSWgyMkpWMkpyWnRuaWhMQnRGQStuUQp2Zk9QcE1LRnJMUU1DWVozMk9Na045T1pWbmNyMmpQNzNhaE9SaWloaGVBczJYTUtybHZmVWVKTFJrSlBlSVB6CnR2TlVacWExMmZ4T0Jsdy9hV1NqVk9lRDVMVm5nUStrQksydGRoL08xSjFWRGgzdVU3RHNZUThmRm1UcWR6ZzYKUWhtbjhaTXFIS3lNeitOdkt1d1h5eEtyeFZKVEl1QzJXZHhGWlZZMzdtZzJ5Vm9OdFhpSFNQMXpxVWV4SHNEKwpzUDBsZy9jUDdlaitOY3Q5WnpudUZBc2U4cUNDZnlaL2hPQ2NCblZabG1GUFgzRCtJSEpVWUpGaWVkYndsZHljCmw1eG1jaFU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBb1ZHdnFwUzVkSzd1dktYRDlWOWFlWjNjTlpsS21VSTlQTUFlNWF5TDFTU2FlUXhjCnoyekJ4UTkxVGJCd3dmQzZYZUxodWsxTjA5NVVPYno2dE5TeCtHelloK2VFYm1oVllHQTBGWk1YY1hOdEdIK3oKUDc3UFBZK0NBQ0tpeHh0clpXZU9FdXYwTHVRUHNHMWZsaWdjSVVMSm82Zk9oWGxZd21rRGl3SEdBMjhsWWcxawpRS0QwaDhpVkhUb3N1SXd5c0VUbEFxRDh1Y05FbWNzVU5OVUV2dXlOaUpSaTVXWVNEZld0bjFtWG01dUE2b2c2CmRKMDNkMHpkZHBHa0V4b1ZUSDAvMCt1RndyTExsTjBMSHJTa2RxeitGSFZweWtuSldCOE5RSzZ4TTlscE5ubksKeml1RnVoakJmZkt1OG51aDdTendGMWhLUm81SUFzZ0tJNDVlUlFJREFRQUJBb0lCQVFDVGlZUGh2TGVJa2R6aQpSN0RhbnVTK1NiUDJpVVlDdU9RTXhhRDhhVHhTS1hIbHQzckNjak1kcVMrZFovc1lSTFFOM2N5WWVNN3ZNRzFUCmlSUzVnYlZyQVJGZjZrdmlOaVd2U1EwWmxqZGdtVEp6cjRjZWk4STZDUi9hUTlNZnltSUVraHNNRHlSNkpqWjcKSXV6REJkZ0VTM0xpN0R3ak1vSU0rOEl6eGVGMWpTT1ErTjlLcTB3QzMzVzFuOVdIYXZWcWZvcjI0bmVySG9FcwozNmlUMncvdkU1dFJBTFlEbjh6MFp5YUM1d3Nnb3FyTG5UWXlMcnVKWnNGa1NxN25GWEE3cjhXL0dLQjBoL3ZaCmNzYkRlWU1WMjJNckdRTzhYSlAwM3J0cm9DQWJmUUhRd3lEbnpsTFJ3blNGRmhjV0F5UW9qbkozb0RQbzhZaXoKam1meVd5WlpBb0dCQU0vZGtqMGhFZm05SHBBL1dyTGVEb0V5WWtKL3N1R3RyWlpSNS9INnJieHphQ2FlQ3B0UApZQ25JcnBoMjRVYWFvaXFJY0pnazRXRjBmU3RhRnh0SkxSYXpBVElUUFlCZjF0OEEwYkhjN3UxMExiWlZkMG5uCk1lWVJPYlhzQXlvdmxNcm1ZclBPWWFXSEtJL1oyT3NLeC83UkhTcnEwZm1ZcUFYSXpzK2V1Ryt6QW9HQkFNYXMKem9YdlJwVDZGNndYaU5QemFqamc5MHJFMFhZZ0g3VkEvWHJsbUp5MVFRYy8rZzJ1ZXVYMGJ5aVhYY0FMY3BINAoybFlYcEZaelNPRkd6Z01DMEtuQkJyWmxsYWIweUczbWhsWjRtbkFhbmtSUFh4bWpDdmgvZmtkYStlQ1RCMFdHCjBOY3RQSFVvSk9GNWpLNmtxVy9rWVpkWVRPV1FjczNybURFWCtENG5Bb0dCQUwwdkhRenp6MGRyMzZoTGNRSUEKWmxVaUJSb2UzVERYQUhraWZLYllqMDFJQUErOW9VdXZWNGRQOWRBZnluS1hCR2NQbk9Kc0ZwQzdFN3prRnNtbgp0UmpHdkp6VnRCRGxxVXQzbEdKOEFSMHVzdmdUR3ltdytOSTY5VHBrM3BDRGs3bURLMndZdHZpUFpkUmU0alV4CnI4cDBpa1pvUjhrU0xrSnRmQVNzb1pKUEFvR0FWSTk4bjNrR082WnVxT3FqYkVMd2RTRWJZQkdCYlp1aW8wejAKRm5qZWllU0R0d2c5NzlEUnNrcGxmWXRmZGJ2cG1jT25lbms1a3lvaVhPLzhBMEFSZkE4U1FsUGViRjlIWjY5MApnaDEyN2p3R0hPRURneS9vSFhoMlVQeWgyam42SUZlUFQrYUxFdnB4S0I3S0NCTkJvc1E3M1dUUjVldWpVWTN6CkN3SSt3SVVDZ1lFQXJVQ0k4cng3MVd4S3A0dnNObTJpM2JlT3lYa3dVaFhKUmhmL0cwZk5vc2FhT0RvVEdNT1oKVlRRci9hVWJlQ2pWMlZENTEyVkJEQlZnYUNnZ1ZZS3pSMXpJSDFlMXZzVjhQVjN1Snh0Q2FLT3daTHV4OS9HQQp0QzJOKzFTY05GWkxtU3Z0MzU2WG5EL3VwRUcyeVMydmFURDU1K3FVUlVFWk1TWDlPdFpSL2JBPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
diff --git a/test/e2e/testdata/backend-tls.yaml b/test/e2e/testdata/backend-tls.yaml
index cdd6960c6d2..f00218ab99c 100644
--- a/test/e2e/testdata/backend-tls.yaml
+++ b/test/e2e/testdata/backend-tls.yaml
@@ -1,105 +1,3 @@
-apiVersion: v1
-data:
- ca.crt: |
- -----BEGIN CERTIFICATE-----
- MIIDQzCCAiugAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYDVQQKEwpFbnZv
- eVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBHYXRld2F5
- IENBMCAXDTI0MDMxMDE1MzIxN1oYDzIxMjQwMzEwMTYzMjE3WjBCMRMwEQYDVQQK
- EwpFbnZveVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBH
- YXRld2F5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7ZFmGB4e
- m1KdGEohAZBfqydAEGLDHJ1YyfHWdd+vBAevdW64bZx3pggJOtgCnePuFd02rDQS
- dlsJlX/6mFtoQilo6wvxDSJRfaTDbtfTjw+7k8yfd/Jsmh0RWG+UeyI7Na9sXAz7
- b57mpxsCoNowzeK5ETiOGGNWPcjENJkSnBarz5muN00xIZWBU+yN5PLJNxZvxpZJ
- Ol/SSI8sno0e0PxAmp3fe7QaXiZj/TAGJPGuTJkUxrHqyZGJtYUxsS8A0dT1zBjj
- izA5Dp+b5yzYo23Hh7BgpbZ7X4gsDThFuwCD6fHyepuv2zHPqvSsdqg2hAhDp91R
- zrn7a9GxG2VSIwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
- AwEB/zAdBgNVHQ4EFgQUUpP1aZ1M2KIuPPWrNPDV2c5CngowDQYJKoZIhvcNAQEL
- BQADggEBAGSEkAVz+Z0qS4FmA0q4SCpIIq64bsdEjiUzev7pK1LEK0/Y28QBPixV
- cUXfax18VPR9pls1JgXto9qY+C0hnRZic6611QTJlWK1p6dinQ/eDdYCBC+nv5xx
- ssASwmplIxMvj3S1qF6dr7sMI2ZVD5HElTWdO19UBLyhiKKZW2KxDsYj+5NRwGFe
- G+JuDgq7njUM8mdyYk0NehefdBUEUUCQtnwUtW95/429XwqQROuRDteGT9kjD+Y5
- ea5mW4mfqLeuGJXZs9bdWjKKdLQPrn9IshPysWqz2Hz8dQ1f7N9/g8UWVSjd4cyx
- S5EAolzVv0yB7wHCWCgfG/ckdOTUNnE=
- -----END CERTIFICATE-----
-kind: ConfigMap
-metadata:
- name: backend-tls-checks-certificate
- namespace: gateway-conformance-infra
----
-apiVersion: v1
-data:
- tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURZVENDQWttZ0F3SUJBZ0lSQUpiK2x5QTJqZCtlUmRMTzR4Sm5kWVF3RFFZSktvWklodmNOQVFFTEJRQXcKUWpFVE1CRUdBMVVFQ2hNS1JXNTJiM2xRY205NGVURVFNQTRHQTFVRUN4TUhSMkYwWlhkaGVURVpNQmNHQTFVRQpBeE1RUlc1MmIza2dSMkYwWlhkaGVTQkRRVEFnRncweU5EQXpNVEF4TlRNeU1UZGFHQTh5TVRJME1ETXhNREUyCk16SXhOMW93SkRFUU1BNEdBMVVFQ2hNSFFXTnRaU0JEYnpFUU1BNEdBMVVFQXhNSFpHVm1ZWFZzZERDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtGUnI2cVV1WFN1N3J5bHcvVmZXbm1kM0RXWgpTcGxDUFR6QUh1V3NpOVVrbW5rTVhNOXN3Y1VQZFUyd2NNSHd1bDNpNGJwTlRkUGVWRG04K3JUVXNmaHMySWZuCmhHNW9WV0JnTkJXVEYzRnpiUmgvc3orK3p6MlBnZ0Fpb3NjYmEyVm5qaExyOUM3a0Q3QnRYNVlvSENGQ3lhT24Kem9WNVdNSnBBNHNCeGdOdkpXSU5aRUNnOUlmSWxSMDZMTGlNTXJCRTVRS2cvTG5EUkpuTEZEVFZCTDdzallpVQpZdVZtRWczMXJaOVpsNXViZ09xSU9uU2ROM2RNM1hhUnBCTWFGVXg5UDlQcmhjS3l5NVRkQ3g2MHBIYXMvaFIxCmFjcEp5VmdmRFVDdXNUUFphVFo1eXM0cmhib1l3WDN5cnZKN29lMHM4QmRZU2thT1NBTElDaU9PWGtVQ0F3RUEKQWFOdU1Hd3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUJNQXdHQTFVZApFd0VCL3dRQ01BQXdId1lEVlIwakJCZ3dGb0FVVXBQMWFaMU0yS0l1UFBXck5QRFYyYzVDbmdvd0ZnWURWUjBSCkJBOHdEWUlMWlhoaGJYQnNaUzVqYjIwd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBMkk1MmhrcEwwTXZmejQKeDk3ZjV6dlR5a1VtRWhDSVowN0g0anM0WVg2a1hLWVBzRDBlaGJFbzZUSWgyMkpWMkpyWnRuaWhMQnRGQStuUQp2Zk9QcE1LRnJMUU1DWVozMk9Na045T1pWbmNyMmpQNzNhaE9SaWloaGVBczJYTUtybHZmVWVKTFJrSlBlSVB6CnR2TlVacWExMmZ4T0Jsdy9hV1NqVk9lRDVMVm5nUStrQksydGRoL08xSjFWRGgzdVU3RHNZUThmRm1UcWR6ZzYKUWhtbjhaTXFIS3lNeitOdkt1d1h5eEtyeFZKVEl1QzJXZHhGWlZZMzdtZzJ5Vm9OdFhpSFNQMXpxVWV4SHNEKwpzUDBsZy9jUDdlaitOY3Q5WnpudUZBc2U4cUNDZnlaL2hPQ2NCblZabG1GUFgzRCtJSEpVWUpGaWVkYndsZHljCmw1eG1jaFU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
- tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBb1ZHdnFwUzVkSzd1dktYRDlWOWFlWjNjTlpsS21VSTlQTUFlNWF5TDFTU2FlUXhjCnoyekJ4UTkxVGJCd3dmQzZYZUxodWsxTjA5NVVPYno2dE5TeCtHelloK2VFYm1oVllHQTBGWk1YY1hOdEdIK3oKUDc3UFBZK0NBQ0tpeHh0clpXZU9FdXYwTHVRUHNHMWZsaWdjSVVMSm82Zk9oWGxZd21rRGl3SEdBMjhsWWcxawpRS0QwaDhpVkhUb3N1SXd5c0VUbEFxRDh1Y05FbWNzVU5OVUV2dXlOaUpSaTVXWVNEZld0bjFtWG01dUE2b2c2CmRKMDNkMHpkZHBHa0V4b1ZUSDAvMCt1RndyTExsTjBMSHJTa2RxeitGSFZweWtuSldCOE5RSzZ4TTlscE5ubksKeml1RnVoakJmZkt1OG51aDdTendGMWhLUm81SUFzZ0tJNDVlUlFJREFRQUJBb0lCQVFDVGlZUGh2TGVJa2R6aQpSN0RhbnVTK1NiUDJpVVlDdU9RTXhhRDhhVHhTS1hIbHQzckNjak1kcVMrZFovc1lSTFFOM2N5WWVNN3ZNRzFUCmlSUzVnYlZyQVJGZjZrdmlOaVd2U1EwWmxqZGdtVEp6cjRjZWk4STZDUi9hUTlNZnltSUVraHNNRHlSNkpqWjcKSXV6REJkZ0VTM0xpN0R3ak1vSU0rOEl6eGVGMWpTT1ErTjlLcTB3QzMzVzFuOVdIYXZWcWZvcjI0bmVySG9FcwozNmlUMncvdkU1dFJBTFlEbjh6MFp5YUM1d3Nnb3FyTG5UWXlMcnVKWnNGa1NxN25GWEE3cjhXL0dLQjBoL3ZaCmNzYkRlWU1WMjJNckdRTzhYSlAwM3J0cm9DQWJmUUhRd3lEbnpsTFJ3blNGRmhjV0F5UW9qbkozb0RQbzhZaXoKam1meVd5WlpBb0dCQU0vZGtqMGhFZm05SHBBL1dyTGVEb0V5WWtKL3N1R3RyWlpSNS9INnJieHphQ2FlQ3B0UApZQ25JcnBoMjRVYWFvaXFJY0pnazRXRjBmU3RhRnh0SkxSYXpBVElUUFlCZjF0OEEwYkhjN3UxMExiWlZkMG5uCk1lWVJPYlhzQXlvdmxNcm1ZclBPWWFXSEtJL1oyT3NLeC83UkhTcnEwZm1ZcUFYSXpzK2V1Ryt6QW9HQkFNYXMKem9YdlJwVDZGNndYaU5QemFqamc5MHJFMFhZZ0g3VkEvWHJsbUp5MVFRYy8rZzJ1ZXVYMGJ5aVhYY0FMY3BINAoybFlYcEZaelNPRkd6Z01DMEtuQkJyWmxsYWIweUczbWhsWjRtbkFhbmtSUFh4bWpDdmgvZmtkYStlQ1RCMFdHCjBOY3RQSFVvSk9GNWpLNmtxVy9rWVpkWVRPV1FjczNybURFWCtENG5Bb0dCQUwwdkhRenp6MGRyMzZoTGNRSUEKWmxVaUJSb2UzVERYQUhraWZLYllqMDFJQUErOW9VdXZWNGRQOWRBZnluS1hCR2NQbk9Kc0ZwQzdFN3prRnNtbgp0UmpHdkp6VnRCRGxxVXQzbEdKOEFSMHVzdmdUR3ltdytOSTY5VHBrM3BDRGs3bURLMndZdHZpUFpkUmU0alV4CnI4cDBpa1pvUjhrU0xrSnRmQVNzb1pKUEFvR0FWSTk4bjNrR082WnVxT3FqYkVMd2RTRWJZQkdCYlp1aW8wejAKRm5qZWllU0R0d2c5NzlEUnNrcGxmWXRmZGJ2cG1jT25lbms1a3lvaVhPLzhBMEFSZkE4U1FsUGViRjlIWjY5MApnaDEyN2p3R0hPRURneS9vSFhoMlVQeWgyam42SUZlUFQrYUxFdnB4S0I3S0NCTkJvc1E3M1dUUjVldWpVWTN6CkN3SSt3SVVDZ1lFQXJVQ0k4cng3MVd4S3A0dnNObTJpM2JlT3lYa3dVaFhKUmhmL0cwZk5vc2FhT0RvVEdNT1oKVlRRci9hVWJlQ2pWMlZENTEyVkJEQlZnYUNnZ1ZZS3pSMXpJSDFlMXZzVjhQVjN1Snh0Q2FLT3daTHV4OS9HQQp0QzJOKzFTY05GWkxtU3Z0MzU2WG5EL3VwRUcyeVMydmFURDU1K3FVUlVFWk1TWDlPdFpSL2JBPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
-kind: Secret
-metadata:
- name: backend-tls-checks-certificate
- namespace: gateway-conformance-infra
-type: kubernetes.io/tls
----
-apiVersion: v1
-kind: Service
-metadata:
- name: tls-backend-2
- namespace: gateway-conformance-infra
-spec:
- selector:
- app: tls-backend-2
- ports:
- - protocol: TCP
- port: 443
- targetPort: 8443
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: tls-backend-2
- namespace: gateway-conformance-infra
- labels:
- app: tls-backend-2
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: tls-backend-2
- template:
- metadata:
- labels:
- app: tls-backend-2
- spec:
- containers:
- - name: tls-backend
- image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e
- volumeMounts:
- - name: secret-volume
- mountPath: /etc/secret-volume
- env:
- - name: POD_NAME
- valueFrom:
- fieldRef:
- fieldPath: metadata.name
- - name: NAMESPACE
- valueFrom:
- fieldRef:
- fieldPath: metadata.namespace
- - name: SERVICE_NAME
- value: tls-backend-2
- - name: TLS_SERVER_CERT
- value: /etc/secret-volume/crt
- - name: TLS_SERVER_PRIVKEY
- value: /etc/secret-volume/key
- resources:
- requests:
- cpu: 10m
- volumes:
- - name: secret-volume
- secret:
- secretName: backend-tls-checks-certificate
- items:
- - key: tls.crt
- path: crt
- - key: tls.key
- path: key
----
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
diff --git a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml
index b4031a94d87..b495a7b9f7e 100644
--- a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml
+++ b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml
@@ -87,3 +87,68 @@ spec:
group: ''
kind: ConfigMap
hostname: grpc-ext-proc.envoygateway
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: http-with-extproc-uds-tls
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ hostnames: ["www.example.com"]
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /uds-processor
+ backendRefs:
+ - name: infra-backend-v1
+ port: 8080
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: grpc-uds-ext-proc
+ namespace: gateway-conformance-infra
+spec:
+ endpoints:
+ - unix:
+ path: /var/run/ext-proc/extproc.sock
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyExtensionPolicy
+metadata:
+ name: ext-proc-uds-test
+ namespace: gateway-conformance-infra
+spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: http-with-extproc-uds-tls
+ extProc:
+ - backendRefs:
+ - kind: Backend
+ group: gateway.envoyproxy.io
+ name: grpc-uds-ext-proc
+ namespace: gateway-conformance-infra
+ processingMode:
+ request: {}
+ response: {}
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+ name: policy-btls-uds-extproc
+ namespace: gateway-conformance-infra
+spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: grpc-uds-ext-proc
+ validation:
+ caCertificateRefs:
+ - name: grpc-ext-proc-ca
+ group: ''
+ kind: ConfigMap
+ hostname: grpc-ext-proc.envoygateway
diff --git a/test/e2e/testdata/ext-proc-service.yaml b/test/e2e/testdata/ext-proc-service.yaml
index e9c48e7fc2f..23b325f2031 100644
--- a/test/e2e/testdata/ext-proc-service.yaml
+++ b/test/e2e/testdata/ext-proc-service.yaml
@@ -99,7 +99,6 @@ data:
log.Fatalf("Failed to load TLS credentials: %v", err)
}
gs := grpc.NewServer(grpc.Creds(creds))
-
envoy_service_proc_v3.RegisterExternalProcessorServer(gs, &extProcServer{})
go func() {
@@ -109,6 +108,40 @@ data:
}
}()
+ // Create Unix listener
+ gus := grpc.NewServer(grpc.Creds(creds))
+ envoy_service_proc_v3.RegisterExternalProcessorServer(gus, &extProcServer{})
+
+ udsAddr := "/var/run/ext-proc/extproc.sock"
+ if _, err := os.Stat(udsAddr); err == nil {
+ if err := os.RemoveAll(udsAddr); err != nil {
+ log.Fatalf("failed to remove: %v", err)
+ }
+ }
+
+ ul, err := net.Listen("unix", udsAddr)
+ if err != nil {
+ log.Fatalf("failed to listen: %v", err)
+ }
+
+ err = os.Chmod(udsAddr, 0700)
+ if err != nil {
+ log.Fatalf("failed to set permissions: %v", err)
+ }
+
+ // envoy distroless uid
+ err = os.Chown(udsAddr, 65532, 0)
+ if err != nil {
+ log.Fatalf("failed to set permissions: %v", err)
+ }
+
+ go func() {
+ err = gus.Serve(ul)
+ if err != nil {
+ log.Fatalf("failed to serve: %v", err)
+ }
+ }()
+
http.HandleFunc("/healthz", healthCheckHandler)
err = http.ListenAndServe(":8080", nil)
if err != nil {
@@ -364,7 +397,7 @@ spec:
command:
- sh
- "-c"
- - "cp -a /app /app-live && cd /app-live && go run . --certPath=/app-live/certs/ "
+ - "cd /app && go run . --certPath=/app/certs/"
image: golang:1.22.3-alpine
ports:
- containerPort: 8000
@@ -373,6 +406,8 @@ spec:
mountPath: /app
- name: grpc-ext-proc-secret
mountPath: /app/certs
+ - name: socket-dir
+ mountPath: /var/run/ext-proc/
readinessProbe:
httpGet:
path: /healthz
@@ -389,6 +424,10 @@ spec:
path: server.crt
- key: tls.key
path: server.key
+ - name: socket-dir
+ hostPath:
+ path: /var/run/ext-proc/
+ type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
diff --git a/test/e2e/testdata/httproute-to-backend-fqdn-http2.yaml b/test/e2e/testdata/httproute-to-backend-fqdn-http2.yaml
new file mode 100644
index 00000000000..15131291fbc
--- /dev/null
+++ b/test/e2e/testdata/httproute-to-backend-fqdn-http2.yaml
@@ -0,0 +1,30 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: httproute-to-backend-fqdn-http2
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /backend-fqdn-http2
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn-http2
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-fqdn-http2
+ namespace: gateway-conformance-infra
+spec:
+ appProtocols:
+ - gateway.envoyproxy.io/h2c
+ endpoints:
+ - fqdn:
+ hostname: infra-backend-v1.gateway-conformance-infra.svc.cluster.local
+ port: 8081
diff --git a/test/e2e/testdata/httproute-to-backend-fqdn-tls.yaml b/test/e2e/testdata/httproute-to-backend-fqdn-tls.yaml
new file mode 100644
index 00000000000..b3f2f34f375
--- /dev/null
+++ b/test/e2e/testdata/httproute-to-backend-fqdn-tls.yaml
@@ -0,0 +1,45 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: httproute-to-fqdn-backend-tls
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /backend-fqdn-tls
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn-tls
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-fqdn-tls
+ namespace: gateway-conformance-infra
+spec:
+ endpoints:
+ - fqdn:
+ hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local
+ port: 443
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+ name: backend-fqdn-tls-btls
+ namespace: gateway-conformance-infra
+spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn-tls
+ validation:
+ caCertificateRefs:
+ - name: backend-tls-checks-certificate
+ group: ""
+ kind: ConfigMap
+ hostname: example.com
diff --git a/test/e2e/testdata/httproute-to-backend-fqdn.yaml b/test/e2e/testdata/httproute-to-backend-fqdn.yaml
new file mode 100644
index 00000000000..bef40eecdf3
--- /dev/null
+++ b/test/e2e/testdata/httproute-to-backend-fqdn.yaml
@@ -0,0 +1,28 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: httproute-to-backend-fqdn
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /backend-fqdn
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn-http2
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-fqdn
+ namespace: gateway-conformance-infra
+spec:
+ endpoints:
+ - fqdn:
+ hostname: infra-backend-v1.gateway-conformance-infra.svc.cluster.local
+ port: 8080
diff --git a/test/e2e/testdata/httproute-to-backend-ip.yaml b/test/e2e/testdata/httproute-to-backend-ip.yaml
new file mode 100644
index 00000000000..de1116d3f8e
--- /dev/null
+++ b/test/e2e/testdata/httproute-to-backend-ip.yaml
@@ -0,0 +1,47 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: infra-backend-v1-clusterip
+ namespace: gateway-conformance-infra
+spec:
+ selector:
+ app: infra-backend-v1
+ clusterIP: 10.96.96.96
+ ports:
+ - protocol: TCP
+ port: 8080
+ name: http11
+ targetPort: 3000
+ - protocol: TCP
+ port: 8081
+ name: http2
+ targetPort: 3001
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: httproute-to-backend-ip
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /backend-ip
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-ip
+ namespace: gateway-conformance-infra
+spec:
+ endpoints:
+ - ip:
+ address: 10.96.96.96
+ port: 8080
diff --git a/test/e2e/tests/ext_proc.go b/test/e2e/tests/ext_proc.go
index eb069380b7b..afa10772551 100644
--- a/test/e2e/tests/ext_proc.go
+++ b/test/e2e/tests/ext_proc.go
@@ -133,5 +133,58 @@ var ExtProcTest = suite.ConformanceTest{
t.Errorf("failed to compare request and response: %v", err)
}
})
+
+ t.Run("http route with uds ext proc", func(t *testing.T) {
+ ns := "gateway-conformance-infra"
+ routeNN := types.NamespacedName{Name: "http-with-ext-proc", Namespace: ns}
+ gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+
+ ancestorRef := gwv1a2.ParentReference{
+ Group: gatewayapi.GroupPtr(gwv1.GroupName),
+ Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Namespace: gatewayapi.NamespacePtr(gwNN.Namespace),
+ Name: gwv1.ObjectName(gwNN.Name),
+ }
+ EnvoyExtensionPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "ext-proc-uds-test", Namespace: ns}, suite.ControllerName, ancestorRef)
+
+ podReady := corev1.PodCondition{Type: corev1.PodReady, Status: corev1.ConditionTrue}
+
+ // Wait for the grpc ext auth service pod to be ready
+ WaitForPods(t, suite.Client, ns, map[string]string{"app": "grpc-ext-proc"}, corev1.PodRunning, podReady)
+
+ expectedResponse := http.ExpectedResponse{
+ Request: http.Request{
+ Host: "www.example.com",
+ Path: "/uds-processor",
+ Headers: map[string]string{
+ "x-request-ext-processed": "true", // header added by ext-processor to backend-bound request
+ "x-request-client-header-received": "original", // this is the original client header preserved by ext-proc in a new header
+ "x-request-client-header": "mutated", // this is the mutated value expected to reach upstream
+ },
+ },
+ Response: http.Response{
+ StatusCode: 200,
+ Headers: map[string]string{
+ "x-response-ext-processed": "true", // header added by ext-processor to client-bound response
+ },
+ },
+ Namespace: ns,
+ }
+
+ req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+
+ // add a request header that will be mutated by ext-proc
+ req.Headers["x-request-client-header"] = []string{"original"}
+
+ cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+ if err != nil {
+ t.Errorf("failed to get expected response: %v", err)
+ }
+
+ if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+ t.Errorf("failed to compare request and response: %v", err)
+ }
+ })
},
}
diff --git a/test/e2e/tests/route_with_backend.go b/test/e2e/tests/route_with_backend.go
new file mode 100644
index 00000000000..fadb195c3d9
--- /dev/null
+++ b/test/e2e/tests/route_with_backend.go
@@ -0,0 +1,110 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+// +build e2e
+
+package tests
+
+import (
+ "testing"
+
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/gateway-api/conformance/utils/http"
+ "sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+ "sigs.k8s.io/gateway-api/conformance/utils/suite"
+)
+
+func init() {
+ ConformanceTests = append(ConformanceTests, EnvoyGatewayBackendTest)
+}
+
+var EnvoyGatewayBackendTest = suite.ConformanceTest{
+ ShortName: "EnvoyGatewayBackendTest",
+ Description: "Routes with a backend ref to a backend",
+ Manifests: []string{
+ "testdata/httproute-to-backend-fqdn.yaml",
+ "testdata/httproute-to-backend-ip.yaml",
+ "testdata/httproute-to-backend-fqdn-http2.yaml",
+ "testdata/httproute-to-backend-fqdn-tls.yaml",
+ },
+ Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+ t.Run("of type FQDN", func(t *testing.T) {
+ ns := "gateway-conformance-infra"
+ routeNN := types.NamespacedName{Name: "httproute-to-backend-fqdn", Namespace: ns}
+ gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+
+ expectedResponse := http.ExpectedResponse{
+ Request: http.Request{
+ Path: "/backend-fqdn",
+ },
+ Response: http.Response{
+ StatusCode: 200,
+ },
+ Namespace: ns,
+ }
+
+ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+ })
+
+ t.Run("of type IP", func(t *testing.T) {
+ ns := "gateway-conformance-infra"
+ routeNN := types.NamespacedName{Name: "httproute-to-backend-ip", Namespace: ns}
+ gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+
+ expectedResponse := http.ExpectedResponse{
+ Request: http.Request{
+ Path: "/backend-ip",
+ },
+ Response: http.Response{
+ StatusCode: 200,
+ },
+ Namespace: ns,
+ }
+
+ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+ })
+
+ t.Run("of type FQDN with HTTP2", func(t *testing.T) {
+ ns := "gateway-conformance-infra"
+ routeNN := types.NamespacedName{Name: "httproute-to-backend-fqdn-http2", Namespace: ns}
+ gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+
+ expectedResponse := http.ExpectedResponse{
+ Request: http.Request{
+ Path: "/backend-fqdn-http2",
+ },
+ Response: http.Response{
+ StatusCode: 200,
+ },
+ Namespace: ns,
+ }
+
+ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+ })
+
+ t.Run("of type FQDN with a backend TLS Policy", func(t *testing.T) {
+ ns := "gateway-conformance-infra"
+ routeNN := types.NamespacedName{Name: "httproute-to-fqdn-backend-tls", Namespace: ns}
+ gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+
+ expectedResponse := http.ExpectedResponse{
+ Request: http.Request{
+ Path: "/backend-fqdn-tls",
+ },
+ Response: http.Response{
+ StatusCode: 200,
+ },
+ Namespace: ns,
+ }
+
+ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+ })
+ },
+}
diff --git a/test/helm/default-config.out.yaml b/test/helm/default-config.out.yaml
index 25326c67742..5184640ee6d 100644
--- a/test/helm/default-config.out.yaml
+++ b/test/helm/default-config.out.yaml
@@ -126,6 +126,7 @@ rules:
- backendtrafficpolicies
- securitypolicies
- envoyextensionpolicies
+ - backends
verbs:
- get
- list
@@ -138,6 +139,7 @@ rules:
- backendtrafficpolicies/status
- securitypolicies/status
- envoyextensionpolicies/status
+ - backends/status
verbs:
- update
- apiGroups:
diff --git a/test/helm/deployment-images-config.out.yaml b/test/helm/deployment-images-config.out.yaml
index b13dc2261a5..f0c15a289e5 100644
--- a/test/helm/deployment-images-config.out.yaml
+++ b/test/helm/deployment-images-config.out.yaml
@@ -126,6 +126,7 @@ rules:
- backendtrafficpolicies
- securitypolicies
- envoyextensionpolicies
+ - backends
verbs:
- get
- list
@@ -138,6 +139,7 @@ rules:
- backendtrafficpolicies/status
- securitypolicies/status
- envoyextensionpolicies/status
+ - backends/status
verbs:
- update
- apiGroups:
diff --git a/test/helm/envoy-gateway-config.out.yaml b/test/helm/envoy-gateway-config.out.yaml
index 612306e1f0e..dd9742e52f6 100644
--- a/test/helm/envoy-gateway-config.out.yaml
+++ b/test/helm/envoy-gateway-config.out.yaml
@@ -128,6 +128,7 @@ rules:
- backendtrafficpolicies
- securitypolicies
- envoyextensionpolicies
+ - backends
verbs:
- get
- list
@@ -140,6 +141,7 @@ rules:
- backendtrafficpolicies/status
- securitypolicies/status
- envoyextensionpolicies/status
+ - backends/status
verbs:
- update
- apiGroups:
diff --git a/test/helm/global-images-config.out.yaml b/test/helm/global-images-config.out.yaml
index 89788eaef1a..51d4df43502 100644
--- a/test/helm/global-images-config.out.yaml
+++ b/test/helm/global-images-config.out.yaml
@@ -130,6 +130,7 @@ rules:
- backendtrafficpolicies
- securitypolicies
- envoyextensionpolicies
+ - backends
verbs:
- get
- list
@@ -142,6 +143,7 @@ rules:
- backendtrafficpolicies/status
- securitypolicies/status
- envoyextensionpolicies/status
+ - backends/status
verbs:
- update
- apiGroups: