Skip to content

Commit 6d629c6

Browse files
feat(kustomize/v2): scaffold NamespaceTransformer for multi-namespace RBAC
Scaffold a commented-out NamespaceTransformer configuration as an opt-in alternative to the "namespace:" field in config/default/kustomization.yaml. When using namespace-scoped RBAC markers (e.g. //+kubebuilder:rbac:namespace=infrastructure), the global "namespace:" field overrides all namespaces, causing ID conflict errors. The NamespaceTransformer with "unsetOnly: true" preserves explicit namespaces while assigning the default namespace to resources without one. Changes: - Add namespace_transformer.go template scaffolding namespace_transformer.yaml - Add commented-out [NAMESPACE-TRANSFORMER] section in kustomization.yaml with inline documentation explaining the ID conflict issue and opt-in steps - Add NOTE comment on the "namespace:" field warning about the override behavior - Register NamespaceTransformer in init.go Default behavior is completely unchanged. Users who need multi-namespace RBAC can follow the inline instructions to switch from the "namespace:" field to the NamespaceTransformer.
1 parent c0e3b37 commit 6d629c6

File tree

445 files changed

+397
-38854
lines changed

Some content is hidden

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

445 files changed

+397
-38854
lines changed

docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Adds namespace to all resources.
2+
# NOTE: If you use namespace-scoped RBAC markers (e.g. //+kubebuilder:rbac:namespace=<ns>),
3+
# the "namespace:" field below will override ALL namespaces — including those explicitly set
4+
# by your RBAC markers — causing "namespace transformation produces ID conflict" errors.
5+
# To fix this, comment out the "namespace:" line below and uncomment the [NAMESPACE-TRANSFORMER]
6+
# section at the bottom of this file. See config/default/namespace_transformer.yaml for details.
27
namespace: project-system
38

49
# Value of this field is prepended to the
@@ -238,3 +243,14 @@ replacements:
238243
# fieldPath: .metadata.name
239244
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
240245
# +kubebuilder:scaffold:crdkustomizecainjectionname
246+
247+
# [NAMESPACE-TRANSFORMER] To enable the NamespaceTransformer (e.g. for multi-namespace RBAC),
248+
# uncomment the "transformers:" section below and comment out the "namespace:" field at the top
249+
# of this file. This allows resources with explicit namespaces (from RBAC markers like
250+
# //+kubebuilder:rbac:namespace=<ns>) to keep their namespaces, while resources without an
251+
# explicit namespace will receive the default project namespace.
252+
# You will also need to remove "namespace: system" from resource files under config/
253+
# so that this transformer can assign the default namespace.
254+
# See config/default/namespace_transformer.yaml for more details.
255+
#transformers:
256+
#- namespace_transformer.yaml
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# This NamespaceTransformer is an alternative to the
2+
# "namespace:" field in kustomization.yaml.
3+
# While the "namespace:" field overrides ALL namespaces (potentially breaking multi-namespace setups),
4+
# this transformer with "unsetOnly: true" only sets namespace on resources that don't already have one.
5+
#
6+
# This is useful when using namespace-scoped RBAC markers such as:
7+
# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,resources=deployments,verbs=get
8+
# which generate Roles with explicit namespaces that should be preserved.
9+
#
10+
# Usage:
11+
# 1. Comment out the "namespace:" field in kustomization.yaml
12+
# 2. Uncomment the "transformers:" section in kustomization.yaml
13+
# 3. Remove "namespace: system" from any resource files under config/ that should
14+
# receive the default namespace from this transformer instead
15+
#
16+
# More info: https://kubectl.docs.kubernetes.io/references/kustomize/builtins/#_namespacetransformer_
17+
apiVersion: builtin
18+
kind: NamespaceTransformer
19+
metadata:
20+
name: namespace-transformer
21+
namespace: project-system
22+
setRoleBindingSubjects: allServiceAccounts
23+
unsetOnly: true
24+
fieldSpecs:
25+
- path: metadata/namespace
26+
create: true

docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Adds namespace to all resources.
2+
# NOTE: If you use namespace-scoped RBAC markers (e.g. //+kubebuilder:rbac:namespace=<ns>),
3+
# the "namespace:" field below will override ALL namespaces — including those explicitly set
4+
# by your RBAC markers — causing "namespace transformation produces ID conflict" errors.
5+
# To fix this, comment out the "namespace:" line below and uncomment the [NAMESPACE-TRANSFORMER]
6+
# section at the bottom of this file. See config/default/namespace_transformer.yaml for details.
27
namespace: project-system
38

49
# Value of this field is prepended to the
@@ -232,3 +237,14 @@ patches:
232237
# fieldPath: .metadata.name
233238
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
234239
# +kubebuilder:scaffold:crdkustomizecainjectionname
240+
241+
# [NAMESPACE-TRANSFORMER] To enable the NamespaceTransformer (e.g. for multi-namespace RBAC),
242+
# uncomment the "transformers:" section below and comment out the "namespace:" field at the top
243+
# of this file. This allows resources with explicit namespaces (from RBAC markers like
244+
# //+kubebuilder:rbac:namespace=<ns>) to keep their namespaces, while resources without an
245+
# explicit namespace will receive the default project namespace.
246+
# You will also need to remove "namespace: system" from resource files under config/
247+
# so that this transformer can assign the default namespace.
248+
# See config/default/namespace_transformer.yaml for more details.
249+
#transformers:
250+
#- namespace_transformer.yaml
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# This NamespaceTransformer is an alternative to the
2+
# "namespace:" field in kustomization.yaml.
3+
# While the "namespace:" field overrides ALL namespaces (potentially breaking multi-namespace setups),
4+
# this transformer with "unsetOnly: true" only sets namespace on resources that don't already have one.
5+
#
6+
# This is useful when using namespace-scoped RBAC markers such as:
7+
# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,resources=deployments,verbs=get
8+
# which generate Roles with explicit namespaces that should be preserved.
9+
#
10+
# Usage:
11+
# 1. Comment out the "namespace:" field in kustomization.yaml
12+
# 2. Uncomment the "transformers:" section in kustomization.yaml
13+
# 3. Remove "namespace: system" from any resource files under config/ that should
14+
# receive the default namespace from this transformer instead
15+
#
16+
# More info: https://kubectl.docs.kubernetes.io/references/kustomize/builtins/#_namespacetransformer_
17+
apiVersion: builtin
18+
kind: NamespaceTransformer
19+
metadata:
20+
name: namespace-transformer
21+
namespace: project-system
22+
setRoleBindingSubjects: allServiceAccounts
23+
unsetOnly: true
24+
fieldSpecs:
25+
- path: metadata/namespace
26+
create: true

docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Adds namespace to all resources.
2+
# NOTE: If you use namespace-scoped RBAC markers (e.g. //+kubebuilder:rbac:namespace=<ns>),
3+
# the "namespace:" field below will override ALL namespaces — including those explicitly set
4+
# by your RBAC markers — causing "namespace transformation produces ID conflict" errors.
5+
# To fix this, comment out the "namespace:" line below and uncomment the [NAMESPACE-TRANSFORMER]
6+
# section at the bottom of this file. See config/default/namespace_transformer.yaml for details.
27
namespace: project-system
38

49
# Value of this field is prepended to the
@@ -256,3 +261,14 @@ replacements:
256261
index: 1
257262
create: true
258263
# +kubebuilder:scaffold:crdkustomizecainjectionname
264+
265+
# [NAMESPACE-TRANSFORMER] To enable the NamespaceTransformer (e.g. for multi-namespace RBAC),
266+
# uncomment the "transformers:" section below and comment out the "namespace:" field at the top
267+
# of this file. This allows resources with explicit namespaces (from RBAC markers like
268+
# //+kubebuilder:rbac:namespace=<ns>) to keep their namespaces, while resources without an
269+
# explicit namespace will receive the default project namespace.
270+
# You will also need to remove "namespace: system" from resource files under config/
271+
# so that this transformer can assign the default namespace.
272+
# See config/default/namespace_transformer.yaml for more details.
273+
#transformers:
274+
#- namespace_transformer.yaml
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# This NamespaceTransformer is an alternative to the
2+
# "namespace:" field in kustomization.yaml.
3+
# While the "namespace:" field overrides ALL namespaces (potentially breaking multi-namespace setups),
4+
# this transformer with "unsetOnly: true" only sets namespace on resources that don't already have one.
5+
#
6+
# This is useful when using namespace-scoped RBAC markers such as:
7+
# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,resources=deployments,verbs=get
8+
# which generate Roles with explicit namespaces that should be preserved.
9+
#
10+
# Usage:
11+
# 1. Comment out the "namespace:" field in kustomization.yaml
12+
# 2. Uncomment the "transformers:" section in kustomization.yaml
13+
# 3. Remove "namespace: system" from any resource files under config/ that should
14+
# receive the default namespace from this transformer instead
15+
#
16+
# More info: https://kubectl.docs.kubernetes.io/references/kustomize/builtins/#_namespacetransformer_
17+
apiVersion: builtin
18+
kind: NamespaceTransformer
19+
metadata:
20+
name: namespace-transformer
21+
namespace: project-system
22+
setRoleBindingSubjects: allServiceAccounts
23+
unsetOnly: true
24+
fieldSpecs:
25+
- path: metadata/namespace
26+
create: true

pkg/plugins/common/kustomize/v2/scaffolds/init.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ func (s *initScaffolder) Scaffold() error {
6767
templates := []machinery.Builder{
6868
&rbac.Kustomization{},
6969
&kdefault.MetricsService{},
70+
&kdefault.NamespaceTransformer{},
7071
&rbac.MetricsAuthRole{},
7172
&rbac.MetricsAuthRoleBinding{},
7273
&rbac.MetricsReaderRole{},

pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ func (f *Kustomization) SetTemplateDefaults() error {
4545
}
4646

4747
const kustomizeTemplate = `# Adds namespace to all resources.
48+
# NOTE: If you use namespace-scoped RBAC markers (e.g. //+kubebuilder:rbac:namespace=<ns>),
49+
# the "namespace:" field below will override ALL namespaces — including those explicitly set
50+
# by your RBAC markers — causing "namespace transformation produces ID conflict" errors.
51+
# To fix this:
52+
# 1. Use the "roleName" parameter in your RBAC markers to give each Role a unique name
53+
# (e.g. //+kubebuilder:rbac:namespace=infra,roleName=infra-role,...)
54+
# 2. Comment out the "namespace:" line below and uncomment the [NAMESPACE-TRANSFORMER]
55+
# section at the bottom of this file to preserve explicit namespaces.
56+
# See config/default/namespace_transformer.yaml for details.
4857
namespace: {{ .ProjectName }}-system
4958
5059
# Value of this field is prepended to the
@@ -278,4 +287,15 @@ patches:
278287
# fieldPath: .metadata.name
279288
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
280289
# +kubebuilder:scaffold:crdkustomizecainjectionname
290+
291+
# [NAMESPACE-TRANSFORMER] To enable the NamespaceTransformer (e.g. for multi-namespace RBAC),
292+
# uncomment the "transformers:" section below and comment out the "namespace:" field at the top
293+
# of this file. This allows resources with explicit namespaces (from RBAC markers like
294+
# //+kubebuilder:rbac:namespace=<ns>) to keep their namespaces, while resources without an
295+
# explicit namespace will receive the default project namespace.
296+
# You will also need to remove "namespace: system" from resource files under config/
297+
# so that this transformer can assign the default namespace.
298+
# See config/default/namespace_transformer.yaml for more details.
299+
#transformers:
300+
#- namespace_transformer.yaml
281301
`
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package kdefault
18+
19+
import (
20+
"path/filepath"
21+
22+
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
23+
)
24+
25+
var _ machinery.Template = &NamespaceTransformer{}
26+
27+
// NamespaceTransformer scaffolds a file that defines the NamespaceTransformer
28+
// for the default overlay folder
29+
type NamespaceTransformer struct {
30+
machinery.TemplateMixin
31+
machinery.ProjectNameMixin
32+
}
33+
34+
// SetTemplateDefaults implements machinery.Template
35+
func (f *NamespaceTransformer) SetTemplateDefaults() error {
36+
if f.Path == "" {
37+
f.Path = filepath.Join("config", "default", "namespace_transformer.yaml")
38+
}
39+
40+
f.TemplateBody = namespaceTransformerTemplate
41+
42+
return nil
43+
}
44+
45+
const namespaceTransformerTemplate = `# This NamespaceTransformer is an alternative to the
46+
# "namespace:" field in kustomization.yaml.
47+
# While the "namespace:" field overrides ALL namespaces (potentially breaking multi-namespace setups),
48+
# this transformer with "unsetOnly: true" only sets namespace on resources that don't already have one.
49+
#
50+
# This is useful when using namespace-scoped RBAC markers such as:
51+
# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,resources=deployments,verbs=get
52+
# which generate Roles with explicit namespaces that should be preserved.
53+
#
54+
# TIP: When using multiple namespaces, also consider using the "roleName" parameter
55+
# in your RBAC markers to give each Role a unique name, e.g.:
56+
# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,roleName=infra-role,...
57+
# This avoids ID conflicts even before switching to the NamespaceTransformer.
58+
#
59+
# Usage:
60+
# 1. Comment out the "namespace:" field in kustomization.yaml
61+
# 2. Uncomment the "transformers:" section in kustomization.yaml
62+
# 3. Remove "namespace: system" from any resource files under config/ that should
63+
# receive the default namespace from this transformer instead
64+
#
65+
# More info: https://kubectl.docs.kubernetes.io/references/kustomize/builtins/#_namespacetransformer_
66+
apiVersion: builtin
67+
kind: NamespaceTransformer
68+
metadata:
69+
name: namespace-transformer
70+
namespace: {{ .ProjectName }}-system
71+
setRoleBindingSubjects: allServiceAccounts
72+
unsetOnly: true
73+
fieldSpecs:
74+
- path: metadata/namespace
75+
create: true
76+
`

testdata/project-v4-multigroup/.custom-gcl.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)