From dfe7cbe468a7bc5fd69bbe3456b9b475166b82ac Mon Sep 17 00:00:00 2001 From: Anshuman Singh C Date: Tue, 21 Oct 2025 10:39:28 +0200 Subject: [PATCH] Allow option to skip tenant namespace creation Signed-off-by: Anshuman Singh C --- cmd/flux/create_tenant.go | 47 +++++++++++-------- cmd/flux/create_tenant_test.go | 5 ++ .../tenant-with-skip-namespace-create.yaml | 27 +++++++++++ 3 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 cmd/flux/testdata/create_tenant/tenant-with-skip-namespace-create.yaml diff --git a/cmd/flux/create_tenant.go b/cmd/flux/create_tenant.go index f2c98c27b2..e98de51e53 100644 --- a/cmd/flux/create_tenant.go +++ b/cmd/flux/create_tenant.go @@ -58,9 +58,10 @@ const ( ) type tenantFlags struct { - namespaces []string - clusterRole string - account string + namespaces []string + clusterRole string + account string + skipNamespace bool } var tenantArgs tenantFlags @@ -69,6 +70,7 @@ func init() { createTenantCmd.Flags().StringSliceVar(&tenantArgs.namespaces, "with-namespace", nil, "namespace belonging to this tenant") createTenantCmd.Flags().StringVar(&tenantArgs.clusterRole, "cluster-role", "cluster-admin", "cluster role of the tenant role binding") createTenantCmd.Flags().StringVar(&tenantArgs.account, "with-service-account", "", "service account belonging to this tenant") + createTenantCmd.Flags().BoolVar(&tenantArgs.skipNamespace, "skip-namespace-create", false, "skip namespace creation (namespace must exist already)") createCmd.AddCommand(createTenantCmd) } @@ -157,7 +159,7 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error { if createArgs.export { for i := range tenantArgs.namespaces { - if err := exportTenant(namespaces[i], accounts[i], roleBindings[i]); err != nil { + if err := exportTenant(namespaces[i], accounts[i], roleBindings[i], tenantArgs.skipNamespace); err != nil { return err } } @@ -173,9 +175,11 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error { } for i := range tenantArgs.namespaces { - logger.Actionf("applying namespace %s", namespaces[i].Name) - if err := upsertNamespace(ctx, kubeClient, namespaces[i]); err != nil { - return err + if !tenantArgs.skipNamespace { + logger.Actionf("applying namespace %s", namespaces[i].Name) + if err := upsertNamespace(ctx, kubeClient, namespaces[i]); err != nil { + return err + } } logger.Actionf("applying service account %s", accounts[i].Name) @@ -284,19 +288,24 @@ func upsertRoleBinding(ctx context.Context, kubeClient client.Client, roleBindin return nil } -func exportTenant(namespace corev1.Namespace, account corev1.ServiceAccount, roleBinding rbacv1.RoleBinding) error { - namespace.TypeMeta = metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Namespace", - } - data, err := yaml.Marshal(namespace) - if err != nil { - return err - } - data = bytes.Replace(data, []byte("spec: {}\n"), []byte(""), 1) +func exportTenant(namespace corev1.Namespace, account corev1.ServiceAccount, roleBinding rbacv1.RoleBinding, skipNamespace bool) error { + var data []byte + var err error - printlnStdout("---") - printlnStdout(resourceToString(data)) + if !skipNamespace { + namespace.TypeMeta = metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Namespace", + } + data, err = yaml.Marshal(namespace) + if err != nil { + return err + } + data = bytes.Replace(data, []byte("spec: {}\n"), []byte(""), 1) + + printlnStdout("---") + printlnStdout(resourceToString(data)) + } account.TypeMeta = metav1.TypeMeta{ APIVersion: "v1", diff --git a/cmd/flux/create_tenant_test.go b/cmd/flux/create_tenant_test.go index f4fadb8f05..c8d03479fb 100644 --- a/cmd/flux/create_tenant_test.go +++ b/cmd/flux/create_tenant_test.go @@ -54,6 +54,11 @@ func TestCreateTenant(t *testing.T) { args: "create tenant dev-team --with-namespace=apps --cluster-role=custom-role --export", assert: assertGoldenFile("./testdata/create_tenant/tenant-with-cluster-role.yaml"), }, + { + name: "tenant with skip namespace create", + args: "create tenant dev-team --with-namespace=apps --cluster-role=cluster-admin --skip-namespace-create --export", + assert: assertGoldenFile("./testdata/create_tenant/tenant-with-skip-namespace-create.yaml"), + }, } for _, tt := range tests { diff --git a/cmd/flux/testdata/create_tenant/tenant-with-skip-namespace-create.yaml b/cmd/flux/testdata/create_tenant/tenant-with-skip-namespace-create.yaml new file mode 100644 index 0000000000..fa3b32b657 --- /dev/null +++ b/cmd/flux/testdata/create_tenant/tenant-with-skip-namespace-create.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + toolkit.fluxcd.io/tenant: dev-team + name: dev-team + namespace: apps +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + toolkit.fluxcd.io/tenant: dev-team + name: dev-team-reconciler + namespace: apps +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: gotk:apps:reconciler +- kind: ServiceAccount + name: dev-team + namespace: apps