Skip to content

Commit b570798

Browse files
authored
Merge branch 'main' into client-wrr
Signed-off-by: Isaac Wilson <isaac.wilson514@gmail.com>
2 parents 4ac8625 + 1005160 commit b570798

56 files changed

Lines changed: 2282 additions & 327 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/v1alpha1/envoyproxy_accesslogging_types.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type ProxyAccessLogSetting struct {
3939
// (1) All Routes.
4040
// (2) Listeners if and only if Envoy does not find a matching route for a request.
4141
// If type is defined, the accesslog settings would apply to the relevant component (as-is).
42-
// +kubebuilder:validation:Enum=Listener;Route
42+
// +kubebuilder:validation:Enum=Listener;Route;Upstream
4343
// +optional
4444
Type *ProxyAccessLogType `json:"type,omitempty"`
4545
}
@@ -55,6 +55,9 @@ const (
5555
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto#envoy-v3-api-field-extensions-filters-network-tcp-proxy-v3-tcpproxy-access-log
5656
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-access-log
5757
ProxyAccessLogTypeRoute ProxyAccessLogType = "Route"
58+
59+
// ProxyAccessLogTypeUpstream defines the accesslog for upstream.
60+
ProxyAccessLogTypeUpstream ProxyAccessLogType = "Upstream"
5861
)
5962

6063
type ProxyAccessLogFormatType string
@@ -67,7 +70,7 @@ const (
6770
)
6871

6972
// ProxyAccessLogFormat defines the format of accesslog.
70-
// By default accesslogs are written to standard output.
73+
// By default, accesslogs are written to standard output.
7174
//
7275
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Text' ? has(self.text) : true",message="If AccessLogFormat type is Text, text field needs to be set."
7376
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Text' ? !has(self.json) : true",message="If AccessLogFormat type is Text, json field must not be set."

api/v1alpha1/tls_types.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,17 @@ const (
157157
type ClientValidationContext struct {
158158
// Optional set to true accepts connections even when a client doesn't present a certificate.
159159
// Defaults to false, which rejects connections without a valid client certificate.
160+
//
161+
// Deprecated: Use Mode instead.
160162
// +optional
161163
Optional bool `json:"optional,omitempty"`
162164

165+
// Mode defines how the Gateway or Listener validates client certificates.
166+
// If not specified, defaults to RequireAndVerify.
167+
//
168+
// +optional
169+
Mode *ClientValidationModeType `json:"mode,omitempty"`
170+
163171
// CACertificateRefs contains one or more references to
164172
// Kubernetes objects that contain TLS certificates of
165173
// the Certificate Authorities that can be used
@@ -199,6 +207,31 @@ type ClientValidationContext struct {
199207
Crl *CrlContext `json:"crl,omitempty"`
200208
}
201209

210+
// ClientValidationModeType defines how a Gateway or Listener validates client certificates.
211+
//
212+
// +kubebuilder:validation:Enum=Request;RequireAny;VerifyIfGiven;RequireAndVerify
213+
type ClientValidationModeType string
214+
215+
const (
216+
// Request indicates that a client certificate is requested
217+
// during the TLS handshake but does not require one.
218+
ClientValidationRequest ClientValidationModeType = "Request"
219+
220+
// RequireAny indicates that a client certificate is required during
221+
// the handshake, but the connection is permitted even when the
222+
// client certificate verification fails.
223+
ClientValidationRequireAny ClientValidationModeType = "RequireAny"
224+
225+
// VerifyIfGiven indicates that a client certificate is requested
226+
// but not required. If presented, the certificate must be valid.
227+
ClientValidationVerifyIfGiven ClientValidationModeType = "VerifyIfGiven"
228+
229+
// RequireAndVerify indicates that a valid client certificate must be
230+
// presented during the handshake and validated
231+
// using CA certificates defined in CACertificateRefs.
232+
ClientValidationRequireAndVerify ClientValidationModeType = "RequireAndVerify"
233+
)
234+
202235
// CrlContext holds certificate revocation list configuration that can be used to validate the client initiating the TLS connection
203236
type CrlContext struct {
204237
// Refs contains one or more references to a Kubernetes ConfigMap or a Kubernetes Secret,

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,10 +1408,22 @@ spec:
14081408
required:
14091409
- refs
14101410
type: object
1411+
mode:
1412+
description: |-
1413+
Mode defines how the Gateway or Listener validates client certificates.
1414+
If not specified, defaults to RequireAndVerify.
1415+
enum:
1416+
- Request
1417+
- RequireAny
1418+
- VerifyIfGiven
1419+
- RequireAndVerify
1420+
type: string
14111421
optional:
14121422
description: |-
14131423
Optional set to true accepts connections even when a client doesn't present a certificate.
14141424
Defaults to false, which rejects connections without a valid client certificate.
1425+
1426+
Deprecated: Use Mode instead.
14151427
type: boolean
14161428
spkiHashes:
14171429
description: |-

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14332,6 +14332,7 @@ spec:
1433214332
enum:
1433314333
- Listener
1433414334
- Route
14335+
- Upstream
1433514336
type: string
1433614337
required:
1433714338
- sinks

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,10 +1407,22 @@ spec:
14071407
required:
14081408
- refs
14091409
type: object
1410+
mode:
1411+
description: |-
1412+
Mode defines how the Gateway or Listener validates client certificates.
1413+
If not specified, defaults to RequireAndVerify.
1414+
enum:
1415+
- Request
1416+
- RequireAny
1417+
- VerifyIfGiven
1418+
- RequireAndVerify
1419+
type: string
14101420
optional:
14111421
description: |-
14121422
Optional set to true accepts connections even when a client doesn't present a certificate.
14131423
Defaults to false, which rejects connections without a valid client certificate.
1424+
1425+
Deprecated: Use Mode instead.
14141426
type: boolean
14151427
spkiHashes:
14161428
description: |-

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14331,6 +14331,7 @@ spec:
1433114331
enum:
1433214332
- Listener
1433314333
- Route
14334+
- Upstream
1433414335
type: string
1433514336
required:
1433614337
- sinks

internal/gatewayapi/clienttrafficpolicy.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,34 @@ func (t *Translator) buildListenerTLSParameters(
871871
namespace: policy.Namespace,
872872
}
873873

874+
// Determine the effective client validation mode.
875+
mode := egv1a1.ClientValidationRequireAndVerify
876+
if tlsParams.ClientValidation.Mode != nil {
877+
mode = *tlsParams.ClientValidation.Mode
878+
} else if tlsParams.ClientValidation.Optional {
879+
// Legacy mapping: Optional=true means VerifyIfGiven.
880+
mode = egv1a1.ClientValidationVerifyIfGiven
881+
}
882+
883+
irTLSConfig.ClientValidationEnabled = true
884+
switch mode {
885+
case egv1a1.ClientValidationRequest:
886+
irTLSConfig.RequireClientCertificate = false
887+
irTLSConfig.AcceptUntrusted = true
888+
case egv1a1.ClientValidationRequireAny:
889+
irTLSConfig.RequireClientCertificate = true
890+
irTLSConfig.AcceptUntrusted = true
891+
case egv1a1.ClientValidationVerifyIfGiven:
892+
irTLSConfig.RequireClientCertificate = false
893+
irTLSConfig.AcceptUntrusted = false
894+
case egv1a1.ClientValidationRequireAndVerify:
895+
irTLSConfig.RequireClientCertificate = true
896+
irTLSConfig.AcceptUntrusted = false
897+
default:
898+
irTLSConfig.RequireClientCertificate = true
899+
irTLSConfig.AcceptUntrusted = false
900+
}
901+
874902
irCACert := &ir.TLSCACertificate{
875903
Name: irTLSCACertName(policy.Namespace, policy.Name),
876904
}
@@ -894,12 +922,21 @@ func (t *Translator) buildListenerTLSParameters(
894922
}
895923
irCACert.Certificate = append(irCACert.Certificate, validCaCertBytes...)
896924
}
925+
926+
// CA certificates are required for verification modes.
927+
if (mode == egv1a1.ClientValidationVerifyIfGiven || mode == egv1a1.ClientValidationRequireAndVerify) && len(irCACert.Certificate) == 0 {
928+
if tlsParams.ClientValidation.Mode == nil && tlsParams.ClientValidation.Optional {
929+
return irTLSConfig, fmt.Errorf(`tls.clientValidation.optional=true requires caCertificateRefs (maps to mode %q)`, mode)
930+
}
931+
return irTLSConfig, fmt.Errorf(`tls.clientValidation.mode %q requires caCertificateRefs`, mode)
932+
}
897933
if len(irCACert.Certificate) > 0 {
898934
irTLSConfig.CACertificate = irCACert
899-
irTLSConfig.RequireClientCertificate = !tlsParams.ClientValidation.Optional
900-
setTLSClientValidationContext(tlsParams.ClientValidation, irTLSConfig)
901935
}
902936

937+
// Apply additional validation context fields (SPKI/cert hashes and SAN matchers) regardless of CA presence.
938+
setTLSClientValidationContext(tlsParams.ClientValidation, irTLSConfig)
939+
903940
irCrl := &ir.TLSCrl{
904941
Name: irTLSCrlName(policy.Namespace, policy.Name),
905942
}

internal/gatewayapi/listener.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,8 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
551551
accessLogType = ptr.To(ir.ProxyAccessLogTypeRoute)
552552
case egv1a1.ProxyAccessLogTypeListener:
553553
accessLogType = ptr.To(ir.ProxyAccessLogTypeListener)
554+
case egv1a1.ProxyAccessLogTypeUpstream:
555+
accessLogType = ptr.To(ir.ProxyAccessLogTypeUpstream)
554556
}
555557
}
556558

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
envoyProxyForGatewayClass:
2+
apiVersion: gateway.envoyproxy.io/v1alpha1
3+
kind: EnvoyProxy
4+
metadata:
5+
namespace: envoy-gateway-system
6+
name: test
7+
spec:
8+
telemetry:
9+
accessLog:
10+
settings:
11+
- format:
12+
type: Text
13+
text: |
14+
Route access log: [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE%\n
15+
sinks:
16+
- type: File
17+
file:
18+
path: /dev/stdout
19+
type: Route
20+
- format:
21+
type: Text
22+
text: |
23+
Listener access log: [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE%\n
24+
sinks:
25+
- type: File
26+
file:
27+
path: /dev/stdout
28+
type: Listener
29+
- format:
30+
type: Text
31+
text: |
32+
Upstream access log: [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE%\n
33+
sinks:
34+
- type: File
35+
file:
36+
path: /dev/stdout
37+
type: Upstream
38+
gateways:
39+
- apiVersion: gateway.networking.k8s.io/v1
40+
kind: Gateway
41+
metadata:
42+
namespace: envoy-gateway
43+
name: gateway-1
44+
spec:
45+
gatewayClassName: envoy-gateway-class
46+
listeners:
47+
- name: http
48+
protocol: HTTP
49+
port: 80
50+
allowedRoutes:
51+
namespaces:
52+
from: All
53+
httpRoutes:
54+
- apiVersion: gateway.networking.k8s.io/v1
55+
kind: HTTPRoute
56+
metadata:
57+
namespace: default
58+
name: http-route-1
59+
spec:
60+
parentRefs:
61+
- name: gateway-1
62+
namespace: envoy-gateway
63+
rules:
64+
- backendRefs:
65+
- name: service-1
66+
port: 8080

0 commit comments

Comments
 (0)