diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml index 34608695873..6c26389d8ad 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml @@ -1,4 +1,5 @@ # Adds namespace to all resources. +# If using namespace-scoped RBAC, see [NAMESPACE-TRANSFORMER] below. namespace: project-system # Value of this field is prepended to the @@ -238,3 +239,10 @@ replacements: # fieldPath: .metadata.name # targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. # +kubebuilder:scaffold:crdkustomizecainjectionname + +# [NAMESPACE-TRANSFORMER] To use the NamespaceTransformer instead of the +# "namespace:" field (e.g. for multi-namespace RBAC), comment out "namespace:" +# above and uncomment the transformers section below. +# See config/default/namespace_transformer.yaml for details. +#transformers: +#- namespace_transformer.yaml diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/default/namespace_transformer.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/default/namespace_transformer.yaml new file mode 100644 index 00000000000..326510644e5 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/default/namespace_transformer.yaml @@ -0,0 +1,39 @@ +# This NamespaceTransformer is an alternative to the +# "namespace:" field in kustomization.yaml. +# While the "namespace:" field overrides ALL namespaces +# (potentially breaking multi-namespace setups), this transformer +# with "unsetOnly: true" only sets namespace on resources +# that don't already have one. +# +# This is useful when using namespace-scoped RBAC markers such as: +# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,... +# which generate Roles with explicit namespaces that should +# be preserved. +# +# TIP: When using multiple namespaces, also consider using the +# "roleName" parameter in your RBAC markers to give each Role +# a unique name, e.g.: +# //+kubebuilder:rbac:namespace=infra,roleName=infra-role,... +# This avoids ID conflicts even before switching to the +# NamespaceTransformer. +# +# Usage: +# 1. Comment out the "namespace:" field in kustomization.yaml +# 2. Uncomment the "transformers:" section in kustomization.yaml +# 3. Remove "namespace: system" from any resource files under +# config/ that should receive the default namespace from +# this transformer instead +# +# More info: +# https://kubectl.docs.kubernetes.io/references/kustomize/builtins/ +# #_namespacetransformer_ +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: namespace-transformer + namespace: project-system +setRoleBindingSubjects: allServiceAccounts +unsetOnly: true +fieldSpecs: + - path: metadata/namespace + create: true diff --git a/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml b/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml index 02fa7e87c35..37eb5b02abb 100644 --- a/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml @@ -1,4 +1,5 @@ # Adds namespace to all resources. +# If using namespace-scoped RBAC, see [NAMESPACE-TRANSFORMER] below. namespace: project-system # Value of this field is prepended to the @@ -232,3 +233,10 @@ patches: # fieldPath: .metadata.name # targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. # +kubebuilder:scaffold:crdkustomizecainjectionname + +# [NAMESPACE-TRANSFORMER] To use the NamespaceTransformer instead of the +# "namespace:" field (e.g. for multi-namespace RBAC), comment out "namespace:" +# above and uncomment the transformers section below. +# See config/default/namespace_transformer.yaml for details. +#transformers: +#- namespace_transformer.yaml diff --git a/docs/book/src/getting-started/testdata/project/config/default/namespace_transformer.yaml b/docs/book/src/getting-started/testdata/project/config/default/namespace_transformer.yaml new file mode 100644 index 00000000000..326510644e5 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/config/default/namespace_transformer.yaml @@ -0,0 +1,39 @@ +# This NamespaceTransformer is an alternative to the +# "namespace:" field in kustomization.yaml. +# While the "namespace:" field overrides ALL namespaces +# (potentially breaking multi-namespace setups), this transformer +# with "unsetOnly: true" only sets namespace on resources +# that don't already have one. +# +# This is useful when using namespace-scoped RBAC markers such as: +# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,... +# which generate Roles with explicit namespaces that should +# be preserved. +# +# TIP: When using multiple namespaces, also consider using the +# "roleName" parameter in your RBAC markers to give each Role +# a unique name, e.g.: +# //+kubebuilder:rbac:namespace=infra,roleName=infra-role,... +# This avoids ID conflicts even before switching to the +# NamespaceTransformer. +# +# Usage: +# 1. Comment out the "namespace:" field in kustomization.yaml +# 2. Uncomment the "transformers:" section in kustomization.yaml +# 3. Remove "namespace: system" from any resource files under +# config/ that should receive the default namespace from +# this transformer instead +# +# More info: +# https://kubectl.docs.kubernetes.io/references/kustomize/builtins/ +# #_namespacetransformer_ +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: namespace-transformer + namespace: project-system +setRoleBindingSubjects: allServiceAccounts +unsetOnly: true +fieldSpecs: + - path: metadata/namespace + create: true diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml index 4444f6125d9..2f4b4f44749 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml @@ -1,4 +1,5 @@ # Adds namespace to all resources. +# If using namespace-scoped RBAC, see [NAMESPACE-TRANSFORMER] below. namespace: project-system # Value of this field is prepended to the @@ -256,3 +257,10 @@ replacements: index: 1 create: true # +kubebuilder:scaffold:crdkustomizecainjectionname + +# [NAMESPACE-TRANSFORMER] To use the NamespaceTransformer instead of the +# "namespace:" field (e.g. for multi-namespace RBAC), comment out "namespace:" +# above and uncomment the transformers section below. +# See config/default/namespace_transformer.yaml for details. +#transformers: +#- namespace_transformer.yaml diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/namespace_transformer.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/namespace_transformer.yaml new file mode 100644 index 00000000000..326510644e5 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/namespace_transformer.yaml @@ -0,0 +1,39 @@ +# This NamespaceTransformer is an alternative to the +# "namespace:" field in kustomization.yaml. +# While the "namespace:" field overrides ALL namespaces +# (potentially breaking multi-namespace setups), this transformer +# with "unsetOnly: true" only sets namespace on resources +# that don't already have one. +# +# This is useful when using namespace-scoped RBAC markers such as: +# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,... +# which generate Roles with explicit namespaces that should +# be preserved. +# +# TIP: When using multiple namespaces, also consider using the +# "roleName" parameter in your RBAC markers to give each Role +# a unique name, e.g.: +# //+kubebuilder:rbac:namespace=infra,roleName=infra-role,... +# This avoids ID conflicts even before switching to the +# NamespaceTransformer. +# +# Usage: +# 1. Comment out the "namespace:" field in kustomization.yaml +# 2. Uncomment the "transformers:" section in kustomization.yaml +# 3. Remove "namespace: system" from any resource files under +# config/ that should receive the default namespace from +# this transformer instead +# +# More info: +# https://kubectl.docs.kubernetes.io/references/kustomize/builtins/ +# #_namespacetransformer_ +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: namespace-transformer + namespace: project-system +setRoleBindingSubjects: allServiceAccounts +unsetOnly: true +fieldSpecs: + - path: metadata/namespace + create: true diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/init.go b/pkg/plugins/common/kustomize/v2/scaffolds/init.go index 74d89d1796c..6d8f0cf6f21 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/init.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/init.go @@ -67,6 +67,7 @@ func (s *initScaffolder) Scaffold() error { templates := []machinery.Builder{ &rbac.Kustomization{}, &kdefault.MetricsService{}, + &kdefault.NamespaceTransformer{}, &rbac.MetricsAuthRole{}, &rbac.MetricsAuthRoleBinding{}, &rbac.MetricsReaderRole{}, diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go index 5d7445654f7..a9b0af0907f 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go @@ -45,6 +45,7 @@ func (f *Kustomization) SetTemplateDefaults() error { } const kustomizeTemplate = `# Adds namespace to all resources. +# If using namespace-scoped RBAC, see [NAMESPACE-TRANSFORMER] below. namespace: {{ .ProjectName }}-system # Value of this field is prepended to the @@ -278,4 +279,11 @@ patches: # fieldPath: .metadata.name # targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. # +kubebuilder:scaffold:crdkustomizecainjectionname + +# [NAMESPACE-TRANSFORMER] To use the NamespaceTransformer instead of the +# "namespace:" field (e.g. for multi-namespace RBAC), comment out "namespace:" +# above and uncomment the transformers section below. +# See config/default/namespace_transformer.yaml for details. +#transformers: +#- namespace_transformer.yaml ` diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/namespace_transformer.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/namespace_transformer.go new file mode 100644 index 00000000000..220a3ad56a5 --- /dev/null +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/namespace_transformer.go @@ -0,0 +1,84 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kdefault + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &NamespaceTransformer{} + +// NamespaceTransformer scaffolds a file that defines the NamespaceTransformer +// for the default overlay folder +type NamespaceTransformer struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults implements machinery.Template +func (f *NamespaceTransformer) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("config", "default", "namespace_transformer.yaml") + } + + f.TemplateBody = namespaceTransformerTemplate + + return nil +} + +const namespaceTransformerTemplate = `# This NamespaceTransformer is an alternative to the +# "namespace:" field in kustomization.yaml. +# While the "namespace:" field overrides ALL namespaces +# (potentially breaking multi-namespace setups), this transformer +# with "unsetOnly: true" only sets namespace on resources +# that don't already have one. +# +# This is useful when using namespace-scoped RBAC markers such as: +# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,... +# which generate Roles with explicit namespaces that should +# be preserved. +# +# TIP: When using multiple namespaces, also consider using the +# "roleName" parameter in your RBAC markers to give each Role +# a unique name, e.g.: +# //+kubebuilder:rbac:namespace=infra,roleName=infra-role,... +# This avoids ID conflicts even before switching to the +# NamespaceTransformer. +# +# Usage: +# 1. Comment out the "namespace:" field in kustomization.yaml +# 2. Uncomment the "transformers:" section in kustomization.yaml +# 3. Remove "namespace: system" from any resource files under +# config/ that should receive the default namespace from +# this transformer instead +# +# More info: +# https://kubectl.docs.kubernetes.io/references/kustomize/builtins/ +# #_namespacetransformer_ +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: namespace-transformer + namespace: {{ .ProjectName }}-system +setRoleBindingSubjects: allServiceAccounts +unsetOnly: true +fieldSpecs: + - path: metadata/namespace + create: true +` diff --git a/testdata/project-v4-multigroup/config/default/kustomization.yaml b/testdata/project-v4-multigroup/config/default/kustomization.yaml index 2388adcaeda..dcd20fcd672 100644 --- a/testdata/project-v4-multigroup/config/default/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/default/kustomization.yaml @@ -1,4 +1,5 @@ # Adds namespace to all resources. +# If using namespace-scoped RBAC, see [NAMESPACE-TRANSFORMER] below. namespace: project-v4-multigroup-system # Value of this field is prepended to the @@ -250,3 +251,10 @@ replacements: index: 1 create: true # +kubebuilder:scaffold:crdkustomizecainjectionname + +# [NAMESPACE-TRANSFORMER] To use the NamespaceTransformer instead of the +# "namespace:" field (e.g. for multi-namespace RBAC), comment out "namespace:" +# above and uncomment the transformers section below. +# See config/default/namespace_transformer.yaml for details. +#transformers: +#- namespace_transformer.yaml diff --git a/testdata/project-v4-multigroup/config/default/namespace_transformer.yaml b/testdata/project-v4-multigroup/config/default/namespace_transformer.yaml new file mode 100644 index 00000000000..afcce776328 --- /dev/null +++ b/testdata/project-v4-multigroup/config/default/namespace_transformer.yaml @@ -0,0 +1,39 @@ +# This NamespaceTransformer is an alternative to the +# "namespace:" field in kustomization.yaml. +# While the "namespace:" field overrides ALL namespaces +# (potentially breaking multi-namespace setups), this transformer +# with "unsetOnly: true" only sets namespace on resources +# that don't already have one. +# +# This is useful when using namespace-scoped RBAC markers such as: +# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,... +# which generate Roles with explicit namespaces that should +# be preserved. +# +# TIP: When using multiple namespaces, also consider using the +# "roleName" parameter in your RBAC markers to give each Role +# a unique name, e.g.: +# //+kubebuilder:rbac:namespace=infra,roleName=infra-role,... +# This avoids ID conflicts even before switching to the +# NamespaceTransformer. +# +# Usage: +# 1. Comment out the "namespace:" field in kustomization.yaml +# 2. Uncomment the "transformers:" section in kustomization.yaml +# 3. Remove "namespace: system" from any resource files under +# config/ that should receive the default namespace from +# this transformer instead +# +# More info: +# https://kubectl.docs.kubernetes.io/references/kustomize/builtins/ +# #_namespacetransformer_ +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: namespace-transformer + namespace: project-v4-multigroup-system +setRoleBindingSubjects: allServiceAccounts +unsetOnly: true +fieldSpecs: + - path: metadata/namespace + create: true diff --git a/testdata/project-v4-with-plugins/config/default/kustomization.yaml b/testdata/project-v4-with-plugins/config/default/kustomization.yaml index a455b3774b1..f03b844a265 100644 --- a/testdata/project-v4-with-plugins/config/default/kustomization.yaml +++ b/testdata/project-v4-with-plugins/config/default/kustomization.yaml @@ -1,4 +1,5 @@ # Adds namespace to all resources. +# If using namespace-scoped RBAC, see [NAMESPACE-TRANSFORMER] below. namespace: project-v4-with-plugins-system # Value of this field is prepended to the @@ -250,3 +251,10 @@ replacements: index: 1 create: true # +kubebuilder:scaffold:crdkustomizecainjectionname + +# [NAMESPACE-TRANSFORMER] To use the NamespaceTransformer instead of the +# "namespace:" field (e.g. for multi-namespace RBAC), comment out "namespace:" +# above and uncomment the transformers section below. +# See config/default/namespace_transformer.yaml for details. +#transformers: +#- namespace_transformer.yaml diff --git a/testdata/project-v4-with-plugins/config/default/namespace_transformer.yaml b/testdata/project-v4-with-plugins/config/default/namespace_transformer.yaml new file mode 100644 index 00000000000..ba037a3cd48 --- /dev/null +++ b/testdata/project-v4-with-plugins/config/default/namespace_transformer.yaml @@ -0,0 +1,39 @@ +# This NamespaceTransformer is an alternative to the +# "namespace:" field in kustomization.yaml. +# While the "namespace:" field overrides ALL namespaces +# (potentially breaking multi-namespace setups), this transformer +# with "unsetOnly: true" only sets namespace on resources +# that don't already have one. +# +# This is useful when using namespace-scoped RBAC markers such as: +# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,... +# which generate Roles with explicit namespaces that should +# be preserved. +# +# TIP: When using multiple namespaces, also consider using the +# "roleName" parameter in your RBAC markers to give each Role +# a unique name, e.g.: +# //+kubebuilder:rbac:namespace=infra,roleName=infra-role,... +# This avoids ID conflicts even before switching to the +# NamespaceTransformer. +# +# Usage: +# 1. Comment out the "namespace:" field in kustomization.yaml +# 2. Uncomment the "transformers:" section in kustomization.yaml +# 3. Remove "namespace: system" from any resource files under +# config/ that should receive the default namespace from +# this transformer instead +# +# More info: +# https://kubectl.docs.kubernetes.io/references/kustomize/builtins/ +# #_namespacetransformer_ +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: namespace-transformer + namespace: project-v4-with-plugins-system +setRoleBindingSubjects: allServiceAccounts +unsetOnly: true +fieldSpecs: + - path: metadata/namespace + create: true diff --git a/testdata/project-v4/config/default/kustomization.yaml b/testdata/project-v4/config/default/kustomization.yaml index e858e214b69..6d513f6963b 100644 --- a/testdata/project-v4/config/default/kustomization.yaml +++ b/testdata/project-v4/config/default/kustomization.yaml @@ -1,4 +1,5 @@ # Adds namespace to all resources. +# If using namespace-scoped RBAC, see [NAMESPACE-TRANSFORMER] below. namespace: project-v4-system # Value of this field is prepended to the @@ -250,3 +251,10 @@ replacements: index: 1 create: true # +kubebuilder:scaffold:crdkustomizecainjectionname + +# [NAMESPACE-TRANSFORMER] To use the NamespaceTransformer instead of the +# "namespace:" field (e.g. for multi-namespace RBAC), comment out "namespace:" +# above and uncomment the transformers section below. +# See config/default/namespace_transformer.yaml for details. +#transformers: +#- namespace_transformer.yaml diff --git a/testdata/project-v4/config/default/namespace_transformer.yaml b/testdata/project-v4/config/default/namespace_transformer.yaml new file mode 100644 index 00000000000..9edd163154b --- /dev/null +++ b/testdata/project-v4/config/default/namespace_transformer.yaml @@ -0,0 +1,39 @@ +# This NamespaceTransformer is an alternative to the +# "namespace:" field in kustomization.yaml. +# While the "namespace:" field overrides ALL namespaces +# (potentially breaking multi-namespace setups), this transformer +# with "unsetOnly: true" only sets namespace on resources +# that don't already have one. +# +# This is useful when using namespace-scoped RBAC markers such as: +# //+kubebuilder:rbac:groups=apps,namespace=infrastructure,... +# which generate Roles with explicit namespaces that should +# be preserved. +# +# TIP: When using multiple namespaces, also consider using the +# "roleName" parameter in your RBAC markers to give each Role +# a unique name, e.g.: +# //+kubebuilder:rbac:namespace=infra,roleName=infra-role,... +# This avoids ID conflicts even before switching to the +# NamespaceTransformer. +# +# Usage: +# 1. Comment out the "namespace:" field in kustomization.yaml +# 2. Uncomment the "transformers:" section in kustomization.yaml +# 3. Remove "namespace: system" from any resource files under +# config/ that should receive the default namespace from +# this transformer instead +# +# More info: +# https://kubectl.docs.kubernetes.io/references/kustomize/builtins/ +# #_namespacetransformer_ +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: namespace-transformer + namespace: project-v4-system +setRoleBindingSubjects: allServiceAccounts +unsetOnly: true +fieldSpecs: + - path: metadata/namespace + create: true