Skip to content

Commit 954c858

Browse files
authored
feat: support ClusterTrustBundle in CACertificateRefs (#6353)
* enable clustertrustbundles in rbac Signed-off-by: zirain <[email protected]> * support ClusterTrustBundle Signed-off-by: zirain <[email protected]>
1 parent af990e7 commit 954c858

File tree

55 files changed

+3532
-324
lines changed

Some content is hidden

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

55 files changed

+3532
-324
lines changed

charts/gateway-helm/templates/_rbac.tpl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ verbs:
231231
- delete
232232
- deletecollection
233233
- patch
234+
- apiGroups:
235+
- certificates.k8s.io
236+
resources:
237+
- clustertrustbundles
238+
verbs:
239+
- list
240+
- get
241+
- watch
234242
{{- end }}
235243

236244
{{- define "eg.rbac.infra.tokenreview" -}}

internal/gatewayapi/backendtlspolicy.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,16 @@ func getCaCertsFromCARefs(namespace string, caCertificates []gwapiv1.LocalObject
327327
} else {
328328
return nil, fmt.Errorf("secret %s not found in namespace %s", caRef.Name, namespace)
329329
}
330+
case resource.KindClusterTrustBundle:
331+
ctb := resources.GetClusterTrustBundle(string(caRef.Name))
332+
if ctb != nil {
333+
if ca != "" {
334+
ca += "\n"
335+
}
336+
ca += ctb.Spec.TrustBundle
337+
} else {
338+
return nil, fmt.Errorf("cluster trust bundle %s not found", caRef.Name)
339+
}
330340
}
331341
}
332342

internal/gatewayapi/clienttrafficpolicy.go

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -835,47 +835,49 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli
835835
}
836836

837837
for _, caCertRef := range tlsParams.ClientValidation.CACertificateRefs {
838-
if caCertRef.Kind == nil || string(*caCertRef.Kind) == resource.KindSecret { // nolint
838+
caCertRefKind := string(ptr.Deref(caCertRef.Kind, resource.KindSecret))
839+
var caCertBytes []byte
840+
switch caCertRefKind {
841+
case resource.KindSecret:
839842
secret, err := t.validateSecretRef(false, from, caCertRef, resources)
840843
if err != nil {
841844
return irTLSConfig, err
842845
}
843846

844-
secretBytes, ok := getCaCertFromSecret(secret)
845-
if !ok || len(secretBytes) == 0 {
847+
secretCertBytes, ok := getCaCertFromSecret(secret)
848+
if !ok || len(secretCertBytes) == 0 {
846849
return irTLSConfig, fmt.Errorf(
847-
"caCertificateRef not found in secret %s", caCertRef.Name)
850+
"caCertificateRef secret [%s] not found", caCertRef.Name)
848851
}
849-
850-
if err := validateCertificate(secretBytes); err != nil {
851-
return irTLSConfig, fmt.Errorf(
852-
"invalid certificate in secret %s: %w", caCertRef.Name, err)
853-
}
854-
855-
irCACert.Certificate = append(irCACert.Certificate, secretBytes...)
856-
857-
} else if string(*caCertRef.Kind) == resource.KindConfigMap {
852+
caCertBytes = secretCertBytes
853+
case resource.KindConfigMap:
858854
configMap, err := t.validateConfigMapRef(false, from, caCertRef, resources)
859855
if err != nil {
860856
return irTLSConfig, err
861857
}
862858

863-
configMapBytes, ok := getCaCertFromConfigMap(configMap)
864-
if !ok || len(configMapBytes) == 0 {
859+
configMapData, ok := getCaCertFromConfigMap(configMap)
860+
if !ok || len(configMapData) == 0 {
865861
return irTLSConfig, fmt.Errorf(
866-
"caCertificateRef not found in configMap %s", caCertRef.Name)
862+
"caCertificateRef configmap [%s] not found", caCertRef.Name)
867863
}
868-
869-
if err := validateCertificate([]byte(configMapBytes)); err != nil {
864+
caCertBytes = []byte(configMapData)
865+
case resource.KindClusterTrustBundle:
866+
trustBundle := resources.GetClusterTrustBundle(string(caCertRef.Name))
867+
if trustBundle == nil {
870868
return irTLSConfig, fmt.Errorf(
871-
"invalid certificate in configmap %s: %w", caCertRef.Name, err)
869+
"caCertificateRef ClusterTrustBundle [%s] not found", caCertRef.Name)
872870
}
871+
caCertBytes = []byte(trustBundle.Spec.TrustBundle)
872+
default:
873+
return irTLSConfig, fmt.Errorf("unsupported caCertificateRef kind:%s", caCertRefKind)
874+
}
873875

874-
irCACert.Certificate = append(irCACert.Certificate, configMapBytes...)
875-
} else {
876+
if err := validateCertificate(caCertBytes); err != nil {
876877
return irTLSConfig, fmt.Errorf(
877-
"unsupported caCertificateRef kind:%s", string(*caCertRef.Kind))
878+
"invalid certificate in %s %s: %w", caCertRefKind, caCertRef.Name, err)
878879
}
880+
irCACert.Certificate = append(irCACert.Certificate, caCertBytes...)
879881
}
880882

881883
if len(irCACert.Certificate) > 0 {

internal/gatewayapi/resource/resource.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"reflect"
1111

1212
"golang.org/x/exp/slices"
13+
certificatesv1b1 "k8s.io/api/certificates/v1beta1"
1314
corev1 "k8s.io/api/core/v1"
1415
discoveryv1 "k8s.io/api/discovery/v1"
1516
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -66,6 +67,8 @@ type Resources struct {
6667
Backends []*egv1a1.Backend `json:"backends,omitempty" yaml:"backends,omitempty"`
6768
HTTPRouteFilters []*egv1a1.HTTPRouteFilter `json:"httpFilters,omitempty" yaml:"httpFilters,omitempty"`
6869

70+
ClusterTrustBundles []*certificatesv1b1.ClusterTrustBundle `json:"clusterTrustBundles,omitempty" yaml:"clusterTrustBundles,omitempty"`
71+
6972
serviceMap map[types.NamespacedName]*corev1.Service
7073
}
7174

@@ -160,6 +163,16 @@ func (r *Resources) GetSecret(namespace, name string) *corev1.Secret {
160163
return nil
161164
}
162165

166+
func (r *Resources) GetClusterTrustBundle(name string) *certificatesv1b1.ClusterTrustBundle {
167+
for _, ctb := range r.ClusterTrustBundles {
168+
if ctb.Name == name {
169+
return ctb
170+
}
171+
}
172+
173+
return nil
174+
}
175+
163176
func (r *Resources) GetConfigMap(namespace, name string) *corev1.ConfigMap {
164177
for _, configMap := range r.ConfigMaps {
165178
if configMap.Namespace == namespace && configMap.Name == name {

internal/gatewayapi/resource/supported_kind.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ const (
2828
KindSecret = "Secret"
2929
KindHTTPRouteFilter = "HTTPRouteFilter"
3030
KindReferenceGrant = "ReferenceGrant"
31+
KindClusterTrustBundle = "ClusterTrustBundle"
3132
)

internal/gatewayapi/resource/zz_generated.deepcopy.go

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
gateways:
2+
- apiVersion: gateway.networking.k8s.io/v1
3+
kind: Gateway
4+
metadata:
5+
name: gateway-btls
6+
namespace: envoy-gateway
7+
spec:
8+
gatewayClassName: envoy-gateway-class
9+
listeners:
10+
- name: http
11+
protocol: HTTP
12+
port: 80
13+
allowedRoutes:
14+
namespaces:
15+
from: All
16+
httpRoutes:
17+
- apiVersion: gateway.networking.k8s.io/v1
18+
kind: HTTPRoute
19+
metadata:
20+
name: httproute-btls
21+
namespace: envoy-gateway
22+
spec:
23+
parentRefs:
24+
- namespace: envoy-gateway
25+
name: gateway-btls
26+
sectionName: http
27+
rules:
28+
- matches:
29+
- path:
30+
type: Exact
31+
value: "/exact"
32+
backendRefs:
33+
- name: http-backend
34+
namespace: backends
35+
port: 8080
36+
37+
referenceGrants:
38+
- apiVersion: gateway.networking.k8s.io/v1alpha2
39+
kind: ReferenceGrant
40+
metadata:
41+
name: refg-route-svc
42+
namespace: backends
43+
spec:
44+
from:
45+
- group: gateway.networking.k8s.io
46+
kind: HTTPRoute
47+
namespace: envoy-gateway
48+
to:
49+
- group: ""
50+
kind: Service
51+
services:
52+
- apiVersion: v1
53+
kind: Service
54+
metadata:
55+
name: http-backend
56+
namespace: backends
57+
spec:
58+
clusterIP: 10.11.12.13
59+
ports:
60+
- port: 8080
61+
name: http
62+
protocol: TCP
63+
targetPort: 8080
64+
65+
endpointSlices:
66+
- apiVersion: discovery.k8s.io/v1
67+
kind: EndpointSlice
68+
metadata:
69+
name: endpointslice-http-backend
70+
namespace: backends
71+
labels:
72+
kubernetes.io/service-name: http-backend
73+
addressType: IPv4
74+
ports:
75+
- name: http
76+
protocol: TCP
77+
port: 8080
78+
endpoints:
79+
- addresses:
80+
- "10.244.0.11"
81+
conditions:
82+
ready: true
83+
clusterTrustBundles:
84+
- apiVersion: certificates.k8s.io/v1beta1
85+
kind: ClusterTrustBundle
86+
metadata:
87+
creationTimestamp: "2025-06-18T03:19:03Z"
88+
name: ca-cluster-trust-bundle
89+
spec:
90+
trustBundle: |
91+
-----BEGIN CERTIFICATE-----
92+
MIIDQzCCAiugAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYDVQQKEwpFbnZv
93+
eVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBHYXRld2F5
94+
IENBMCAXDTI0MDMxMDE1MzIxN1oYDzIxMjQwMzEwMTYzMjE3WjBCMRMwEQYDVQQK
95+
EwpFbnZveVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBH
96+
YXRld2F5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7ZFmGB4e
97+
m1KdGEohAZBfqydAEGLDHJ1YyfHWdd+vBAevdW64bZx3pggJOtgCnePuFd02rDQS
98+
dlsJlX/6mFtoQilo6wvxDSJRfaTDbtfTjw+7k8yfd/Jsmh0RWG+UeyI7Na9sXAz7
99+
b57mpxsCoNowzeK5ETiOGGNWPcjENJkSnBarz5muN00xIZWBU+yN5PLJNxZvxpZJ
100+
Ol/SSI8sno0e0PxAmp3fe7QaXiZj/TAGJPGuTJkUxrHqyZGJtYUxsS8A0dT1zBjj
101+
izA5Dp+b5yzYo23Hh7BgpbZ7X4gsDThFuwCD6fHyepuv2zHPqvSsdqg2hAhDp91R
102+
zrn7a9GxG2VSIwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
103+
AwEB/zAdBgNVHQ4EFgQUUpP1aZ1M2KIuPPWrNPDV2c5CngowDQYJKoZIhvcNAQEL
104+
BQADggEBAGSEkAVz+Z0qS4FmA0q4SCpIIq64bsdEjiUzev7pK1LEK0/Y28QBPixV
105+
cUXfax18VPR9pls1JgXto9qY+C0hnRZic6611QTJlWK1p6dinQ/eDdYCBC+nv5xx
106+
ssASwmplIxMvj3S1qF6dr7sMI2ZVD5HElTWdO19UBLyhiKKZW2KxDsYj+5NRwGFe
107+
G+JuDgq7njUM8mdyYk0NehefdBUEUUCQtnwUtW95/429XwqQROuRDteGT9kjD+Y5
108+
ea5mW4mfqLeuGJXZs9bdWjKKdLQPrn9IshPysWqz2Hz8dQ1f7N9/g8UWVSjd4cyx
109+
S5EAolzVv0yB7wHCWCgfG/ckdOTUNnE=
110+
-----END CERTIFICATE-----
111+
backendTLSPolicies:
112+
- apiVersion: gateway.networking.k8s.io/v1alpha2
113+
kind: BackendTLSPolicy
114+
metadata:
115+
name: policy-btls
116+
namespace: backends
117+
spec:
118+
targetRefs:
119+
- group: ""
120+
kind: Service
121+
name: http-backend
122+
sectionName: http
123+
validation:
124+
caCertificateRefs:
125+
- name: ca-cluster-trust-bundle
126+
group: ""
127+
kind: ClusterTrustBundle
128+
hostname: example.com

0 commit comments

Comments
 (0)