Skip to content

Commit c577d2b

Browse files
committed
fix(charts): Skip cluster-scope RBAC on namespaced
* Restore tenant-friendly installs by keeping RBAC namespaced if `.Values.gatewayNamespace` is set * `namespaced=true` and `gatewayNamespace` set results in a namespaced Role and Rolebinding for listing namespaces * `namespaced=true` AND `gatewayNamespace` unset will retain the original `ClusterRole` and `ClusterRoleBinding` * `namespace=false` will retain the original `ClusterRole` and `ClusterRoleBinding` * No breaking changes introduced Ticket: #5832 Signed-off-by: Tobias Harnickell <[email protected]>
1 parent ad3d958 commit c577d2b

File tree

8 files changed

+37
-10
lines changed

8 files changed

+37
-10
lines changed

charts/external-dns/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ For set up for a specific provider using the Helm chart, see the following links
6161
external-dns supports running on a namespaced only scope, too.
6262
If `namespaced=true` is defined, the helm chart will setup `Roles` and `RoleBindings` instead `ClusterRoles` and `ClusterRoleBindings`.
6363

64+
Note: When using Gateway API sources in namespaced mode, a cluster-scoped permission to list namespaces is required, unless you also set `gatewayNamespace`. If you set `gatewayNamespace`, all RBAC remains namespaced and no `ClusterRole`/`ClusterRoleBinding` is created.
65+
6466
### Limited Supported
6567

6668
Not all sources are supported in namespaced scope, since some sources depends on cluster-wide resources.
@@ -110,7 +112,7 @@ If `namespaced` is set to `true`, please ensure that `sources` my only contains
110112
| extraVolumeMounts | list | `[]` | Extra [volume mounts](https://kubernetes.io/docs/concepts/storage/volumes/) for the `external-dns` container. |
111113
| extraVolumes | list | `[]` | Extra [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) for the `Pod`. |
112114
| fullnameOverride | string | `nil` | Override the full name of the chart. |
113-
| gatewayNamespace | string | `nil` | _Gateway API_ gateway namespace to watch. |
115+
| gatewayNamespace | string | `nil` | _Gateway API_ gateway namespace to watch. When `namespaced=true`, setting this value avoids creating any cluster-scoped RBAC (no ClusterRole/ClusterRoleBinding) for Gateway sources. |
114116
| global.imagePullSecrets | list | `[]` | Global image pull secrets. |
115117
| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy for the `external-dns` container. |
116118
| image.repository | string | `"registry.k8s.io/external-dns/external-dns"` | Image repository for the `external-dns` container. |

charts/external-dns/README.md.gotmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ For set up for a specific provider using the Helm chart, see the following links
5656
external-dns supports running on a namespaced only scope, too.
5757
If `namespaced=true` is defined, the helm chart will setup `Roles` and `RoleBindings` instead `ClusterRoles` and `ClusterRoleBindings`.
5858

59+
Note: When using Gateway API sources in namespaced mode, a cluster-scoped permission to list namespaces is required, unless you also set `gatewayNamespace`. If you set `gatewayNamespace`, all RBAC remains namespaced and no `ClusterRole`/`ClusterRoleBinding` is created.
60+
5961
### Limited Supported
6062

6163
Not all sources are supported in namespaced scope, since some sources depends on cluster-wide resources.

charts/external-dns/templates/clusterrole.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ rules:
134134
{{- toYaml . | nindent 2 }}
135135
{{- end }}
136136
{{- if and .Values.rbac.create .Values.namespaced (include "external-dns.hasGatewaySources" .) }}
137+
{{- /*
138+
If namespaced=true and gatewayNamespace is NOT set, we need to list namespaces
139+
cluster-wide to discover Gateways across the cluster. In that case, create a
140+
ClusterRole to grant access to namespaces. If gatewayNamespace IS set, we are
141+
fully namespaced for both scopes and can skip cluster-wide RBAC.
142+
*/ -}}
143+
{{- if not .Values.gatewayNamespace }}
137144
---
138145
apiVersion: rbac.authorization.k8s.io/v1
139146
kind: ClusterRole
@@ -145,6 +152,7 @@ rules:
145152
- apiGroups: [""]
146153
resources: ["namespaces"]
147154
verbs: ["get","watch","list"]
155+
{{- end }}
148156
{{- if .Values.gatewayNamespace }}
149157
---
150158
apiVersion: rbac.authorization.k8s.io/v1

charts/external-dns/templates/clusterrolebinding.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ subjects:
1414
name: {{ template "external-dns.serviceAccountName" . }}
1515
namespace: {{ .Release.Namespace }}
1616
{{- if and .Values.rbac.create .Values.namespaced (include "external-dns.hasGatewaySources" .) }}
17+
{{- /*
18+
If namespaced=true and gatewayNamespace is NOT set, bind the namespaces ClusterRole.
19+
If gatewayNamespace IS set, we skip cluster-scoped RBAC entirely.
20+
*/ -}}
21+
{{- if not .Values.gatewayNamespace }}
1722
---
1823
apiVersion: rbac.authorization.k8s.io/v1
1924
kind: ClusterRoleBinding
@@ -29,6 +34,7 @@ subjects:
2934
- kind: ServiceAccount
3035
name: {{ template "external-dns.serviceAccountName" . }}
3136
namespace: {{ .Release.Namespace }}
37+
{{- end }}
3238
{{- if .Values.gatewayNamespace }}
3339
---
3440
apiVersion: rbac.authorization.k8s.io/v1

charts/external-dns/tests/json-schema_test.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ tests:
3030
enabled: "abrakadabra"
3131
asserts:
3232
- failedTemplate:
33-
errorPattern: "Invalid type. Expected: [boolean,null], given: string"
33+
# Accept Helm/JSONSchema error message variations across versions
34+
errorPattern: "(Invalid type\\. Expected: \\[[bB]oolean,null\\], given: string|at '/enabled': got string, want null or boolean)"
3435

3536
- it: should fail if provider is null
3637
set:

charts/external-dns/tests/rbac_test.yaml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,19 +229,19 @@ tests:
229229
value: rbac-external-dns-viewer
230230
template: clusterrolebinding.yaml
231231

232-
- it: should create all required resources when namespaced=true and gatewayNamespace is specified
232+
- it: should create only namespaced RBAC when namespaced=true and gatewayNamespace is specified
233233
set:
234234
namespaced: true
235235
gatewayNamespace: gateway-ns
236236
sources:
237237
- gateway-httproute
238238
asserts:
239-
# Should have: main Role + ClusterRole for namespaces + Gateway Role
239+
# Should have: main Role + Gateway Role only (no cluster-scoped RBAC)
240240
- hasDocuments:
241-
count: 3
241+
count: 2
242242
template: clusterrole.yaml
243243
- hasDocuments:
244-
count: 3
244+
count: 2
245245
template: clusterrolebinding.yaml
246246

247247
# Main role should exist and contain route permissions but NOT gateway permissions
@@ -272,12 +272,18 @@ tests:
272272
value: rbac-external-dns
273273
template: clusterrole.yaml
274274

275-
# ClusterRole for namespaces should exist
275+
# Both documents should be Roles (no ClusterRole present)
276276
- isKind:
277-
of: ClusterRole
277+
of: Role
278278
documentSelector:
279279
path: metadata.name
280-
value: rbac-external-dns-namespaces
280+
value: rbac-external-dns
281+
template: clusterrole.yaml
282+
- isKind:
283+
of: Role
284+
documentSelector:
285+
path: metadata.name
286+
value: rbac-external-dns-gateway
281287
template: clusterrole.yaml
282288

283289
# Gateway role should exist and have gateway permissions only

charts/external-dns/values.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
]
106106
},
107107
"gatewayNamespace": {
108-
"description": "_Gateway API_ gateway namespace to watch.",
108+
"description": "_Gateway API_ gateway namespace to watch. When `namespaced=true`, setting this value avoids creating any cluster-scoped RBAC (no ClusterRole/ClusterRoleBinding) for Gateway sources.",
109109
"type": [
110110
"string",
111111
"null"

charts/external-dns/values.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ triggerLoopOnEvent: false
206206
namespaced: false
207207

208208
# -- _Gateway API_ gateway namespace to watch.
209+
# When `namespaced=true`, setting this value avoids creating any cluster-scoped RBAC
210+
# (no ClusterRole/ClusterRoleBinding) for Gateway sources.
209211
gatewayNamespace: # @schema type:[string, null]; default: null
210212

211213
# -- _Kubernetes_ resources to monitor for DNS entries.

0 commit comments

Comments
 (0)