Skip to content

Commit 9bb7f28

Browse files
authored
Merge branch 'main' into improv-validateClusterStatName
2 parents 1fe223b + 114eab3 commit 9bb7f28

19 files changed

+838
-63
lines changed

api/v1alpha1/clienttrafficpolicy_types.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,19 @@ type HTTP1Settings struct {
357357

358358
// HTTP10Settings provides HTTP/1.0 configuration on the listener.
359359
type HTTP10Settings struct {
360-
// UseDefaultHost defines if the HTTP/1.0 request is missing the Host header,
361-
// then the hostname associated with the listener should be injected into the
362-
// request.
363-
// If this is not set and an HTTP/1.0 request arrives without a host, then
364-
// it will be rejected.
360+
// UseDefaultHost specifies whether a default Host header should be injected
361+
// into HTTP/1.0 requests that do not include one.
362+
//
363+
// When set to true, Envoy Gateway injects the hostname associated with the
364+
// listener or route into the request, in the following order:
365+
//
366+
// 1. If the targeted listener has a non-wildcard hostname, use that hostname.
367+
// 2. If there is exactly one HTTPRoute with a non-wildcard hostname under
368+
// the targeted listener, use that hostname.
369+
//
370+
// Note: Setting this field to true without a non-wildcard hostname makes the
371+
// ClientTrafficPolicy invalid.
372+
//
365373
// +optional
366374
UseDefaultHost *bool `json:"useDefaultHost,omitempty"`
367375
}

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -604,11 +604,18 @@ spec:
604604
properties:
605605
useDefaultHost:
606606
description: |-
607-
UseDefaultHost defines if the HTTP/1.0 request is missing the Host header,
608-
then the hostname associated with the listener should be injected into the
609-
request.
610-
If this is not set and an HTTP/1.0 request arrives without a host, then
611-
it will be rejected.
607+
UseDefaultHost specifies whether a default Host header should be injected
608+
into HTTP/1.0 requests that do not include one.
609+
610+
When set to true, Envoy Gateway injects the hostname associated with the
611+
listener or route into the request, in the following order:
612+
613+
1. If the targeted listener has a non-wildcard hostname, use that hostname.
614+
2. If there is exactly one HTTPRoute with a non-wildcard hostname under
615+
the targeted listener, use that hostname.
616+
617+
Note: Setting this field to true without a non-wildcard hostname makes the
618+
ClientTrafficPolicy invalid.
612619
type: boolean
613620
type: object
614621
preserveHeaderCase:

charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -603,11 +603,18 @@ spec:
603603
properties:
604604
useDefaultHost:
605605
description: |-
606-
UseDefaultHost defines if the HTTP/1.0 request is missing the Host header,
607-
then the hostname associated with the listener should be injected into the
608-
request.
609-
If this is not set and an HTTP/1.0 request arrives without a host, then
610-
it will be rejected.
606+
UseDefaultHost specifies whether a default Host header should be injected
607+
into HTTP/1.0 requests that do not include one.
608+
609+
When set to true, Envoy Gateway injects the hostname associated with the
610+
listener or route into the request, in the following order:
611+
612+
1. If the targeted listener has a non-wildcard hostname, use that hostname.
613+
2. If there is exactly one HTTPRoute with a non-wildcard hostname under
614+
the targeted listener, use that hostname.
615+
616+
Note: Setting this field to true without a non-wildcard hostname makes the
617+
ClientTrafficPolicy invalid.
611618
type: boolean
612619
type: object
613620
preserveHeaderCase:

internal/gatewayapi/backend.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
1919
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
20+
"github.com/envoyproxy/gateway/internal/utils/net"
2021
)
2122

2223
func (t *Translator) ProcessBackends(backends []*egv1a1.Backend, backendTLSPolicies []*gwapiv1.BackendTLSPolicy) []*egv1a1.Backend {
@@ -27,7 +28,7 @@ func (t *Translator) ProcessBackends(backends []*egv1a1.Backend, backendTLSPolic
2728
status.UpdateBackendStatusAcceptedCondition(backend, false,
2829
"The Backend was not accepted since Backend is not enabled in Envoy Gateway Config")
2930
} else {
30-
if err := validateBackend(backend, backendTLSPolicies); err != nil {
31+
if err := validateBackend(backend, backendTLSPolicies, t.RunningOnHost); err != nil {
3132
status.UpdateBackendStatusAcceptedCondition(backend, false, fmt.Sprintf("The Backend was not accepted: %s", err.Error()))
3233
} else {
3334
status.UpdateBackendStatusAcceptedCondition(backend, true, "The Backend was accepted")
@@ -40,7 +41,7 @@ func (t *Translator) ProcessBackends(backends []*egv1a1.Backend, backendTLSPolic
4041
return res
4142
}
4243

43-
func validateBackend(backend *egv1a1.Backend, backendTLSPolicies []*gwapiv1.BackendTLSPolicy) status.Error {
44+
func validateBackend(backend *egv1a1.Backend, backendTLSPolicies []*gwapiv1.BackendTLSPolicy, runningOnHost bool) status.Error {
4445
if backend.Spec.Type != nil && *backend.Spec.Type == egv1a1.BackendTypeDynamicResolver {
4546
if len(backend.Spec.Endpoints) > 0 {
4647
return status.NewRouteStatusError(
@@ -57,13 +58,13 @@ func validateBackend(backend *egv1a1.Backend, backendTLSPolicies []*gwapiv1.Back
5758

5859
for _, ep := range backend.Spec.Endpoints {
5960
if ep.Hostname != nil {
60-
routeErr := validateHostname(*ep.Hostname, "hostname")
61+
routeErr := validateHostname(*ep.Hostname, "hostname", runningOnHost)
6162
if routeErr != nil {
6263
return routeErr
6364
}
6465
}
6566
if ep.FQDN != nil {
66-
routeErr := validateHostname(ep.FQDN.Hostname, "FQDN")
67+
routeErr := validateHostname(ep.FQDN.Hostname, "FQDN", runningOnHost)
6768
if routeErr != nil {
6869
return routeErr
6970
}
@@ -74,9 +75,9 @@ func validateBackend(backend *egv1a1.Backend, backendTLSPolicies []*gwapiv1.Back
7475
fmt.Errorf("IP address %s is invalid", ep.IP.Address),
7576
status.RouteReasonInvalidAddress,
7677
)
77-
} else if ip.IsLoopback() {
78+
} else if ip.IsLoopback() && !runningOnHost {
7879
return status.NewRouteStatusError(
79-
fmt.Errorf("IP address %s in the loopback range is not supported", ep.IP.Address),
80+
fmt.Errorf("IP address %s in the loopback range is only supported when using the Host infrastructure", ep.IP.Address),
8081
status.RouteReasonInvalidAddress,
8182
)
8283
}
@@ -169,15 +170,16 @@ func validateBackendTLSSettings(backend *egv1a1.Backend, backendTLSPolicies []*g
169170
return nil
170171
}
171172

172-
func validateHostname(hostname, typeName string) *status.RouteStatusError {
173+
func validateHostname(hostname, typeName string, allowLocalhost bool) *status.RouteStatusError {
173174
// must be a valid hostname
174175
if errs := validation.IsDNS1123Subdomain(hostname); errs != nil {
175176
return status.NewRouteStatusError(
176177
fmt.Errorf("hostname %s is not a valid %s", hostname, typeName),
177178
status.RouteReasonInvalidAddress,
178179
)
179180
}
180-
if len(strings.Split(hostname, ".")) < 2 {
181+
isLocalHostname := allowLocalhost && hostname == net.DefaultLocalAddress
182+
if !isLocalHostname && len(strings.Split(hostname, ".")) < 2 {
181183
return status.NewRouteStatusError(
182184
fmt.Errorf("hostname %s should be a domain with at least two segments separated by dots", hostname),
183185
status.RouteReasonInvalidAddress,

internal/gatewayapi/listener.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,9 @@ func validCELExpression(expr string) bool {
891891
// servicePortToContainerPort translates a service port into an ephemeral
892892
// container port.
893893
func (t *Translator) servicePortToContainerPort(servicePort int32, envoyProxy *egv1a1.EnvoyProxy) int32 {
894-
if t.ListenerPortShiftDisabled {
894+
// When running on the local host using the Host infrastructure provider, disable translating the
895+
// gateway listener port into a non-privileged port and reuse the specified value.
896+
if t.RunningOnHost {
895897
return servicePort
896898
}
897899

internal/gatewayapi/runner/runner.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,17 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re
146146
for _, resources := range *val {
147147
// Translate and publish IRs.
148148
t := &gatewayapi.Translator{
149-
GatewayControllerName: r.EnvoyGateway.Gateway.ControllerName,
150-
GatewayClassName: gwapiv1.ObjectName(resources.GatewayClass.Name),
151-
GlobalRateLimitEnabled: r.EnvoyGateway.RateLimit != nil,
152-
EnvoyPatchPolicyEnabled: r.EnvoyGateway.ExtensionAPIs != nil && r.EnvoyGateway.ExtensionAPIs.EnableEnvoyPatchPolicy,
153-
BackendEnabled: r.EnvoyGateway.ExtensionAPIs != nil && r.EnvoyGateway.ExtensionAPIs.EnableBackend,
154-
ControllerNamespace: r.ControllerNamespace,
155-
GatewayNamespaceMode: r.EnvoyGateway.GatewayNamespaceMode(),
156-
MergeGateways: gatewayapi.IsMergeGatewaysEnabled(resources),
157-
WasmCache: r.wasmCache,
158-
ListenerPortShiftDisabled: r.EnvoyGateway.Provider != nil && r.EnvoyGateway.Provider.IsRunningOnHost(),
159-
Logger: r.Logger,
149+
GatewayControllerName: r.EnvoyGateway.Gateway.ControllerName,
150+
GatewayClassName: gwapiv1.ObjectName(resources.GatewayClass.Name),
151+
GlobalRateLimitEnabled: r.EnvoyGateway.RateLimit != nil,
152+
EnvoyPatchPolicyEnabled: r.EnvoyGateway.ExtensionAPIs != nil && r.EnvoyGateway.ExtensionAPIs.EnableEnvoyPatchPolicy,
153+
BackendEnabled: r.EnvoyGateway.ExtensionAPIs != nil && r.EnvoyGateway.ExtensionAPIs.EnableBackend,
154+
ControllerNamespace: r.ControllerNamespace,
155+
GatewayNamespaceMode: r.EnvoyGateway.GatewayNamespaceMode(),
156+
MergeGateways: gatewayapi.IsMergeGatewaysEnabled(resources),
157+
WasmCache: r.wasmCache,
158+
RunningOnHost: r.EnvoyGateway.Provider != nil && r.EnvoyGateway.Provider.IsRunningOnHost(),
159+
Logger: r.Logger,
160160
}
161161

162162
// If an extension is loaded, pass its supported groups/kinds to the translator

internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ backends:
4848
conditions:
4949
- lastTransitionTime: null
5050
message: 'The Backend was not accepted: IP address 127.0.0.3 in the loopback
51-
range is not supported'
51+
range is only supported when using the Host infrastructure'
5252
reason: Accepted
5353
status: "False"
5454
type: Invalid
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
backends:
2+
- apiVersion: gateway.envoyproxy.io/v1alpha1
3+
kind: Backend
4+
metadata:
5+
name: backend-fqdn
6+
namespace: default
7+
spec:
8+
endpoints:
9+
- fqdn:
10+
hostname: 'localhost'
11+
port: 3000
12+
- apiVersion: gateway.envoyproxy.io/v1alpha1
13+
kind: Backend
14+
metadata:
15+
name: backend-fqdn
16+
namespace: default
17+
spec:
18+
endpoints:
19+
- ip:
20+
address: '127.0.0.3'
21+
port: 3000
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
backends:
2+
- apiVersion: gateway.envoyproxy.io/v1alpha1
3+
kind: Backend
4+
metadata:
5+
name: backend-fqdn
6+
namespace: default
7+
spec:
8+
endpoints:
9+
- fqdn:
10+
hostname: localhost
11+
port: 3000
12+
status:
13+
conditions:
14+
- lastTransitionTime: null
15+
message: The Backend was accepted
16+
reason: Accepted
17+
status: "True"
18+
type: Accepted
19+
- apiVersion: gateway.envoyproxy.io/v1alpha1
20+
kind: Backend
21+
metadata:
22+
name: backend-fqdn
23+
namespace: default
24+
spec:
25+
endpoints:
26+
- ip:
27+
address: 127.0.0.3
28+
port: 3000
29+
status:
30+
conditions:
31+
- lastTransitionTime: null
32+
message: The Backend was accepted
33+
reason: Accepted
34+
status: "True"
35+
type: Accepted
36+
infraIR: {}
37+
xdsIR: {}

0 commit comments

Comments
 (0)