From c3a9291d1c83952aa4524787c8762957f362f4a4 Mon Sep 17 00:00:00 2001 From: Chris Werner Rau Date: Fri, 8 Nov 2024 10:22:06 +0100 Subject: [PATCH] feat(base-cluster/rbac)!: allow to use the k8s default ClusterRoles The most often used rbac roles are exactly the default ones, this eases that configuration this is breaking because one might already use these names, but they are now forbidden --- charts/base-cluster/templates/rbac/_rbac.tpl | 72 +++++++++++-------- .../templates/rbac/roleBindings.yaml | 5 +- charts/base-cluster/templates/rbac/roles.yaml | 4 ++ 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/charts/base-cluster/templates/rbac/_rbac.tpl b/charts/base-cluster/templates/rbac/_rbac.tpl index 095e1438a..4d5862253 100644 --- a/charts/base-cluster/templates/rbac/_rbac.tpl +++ b/charts/base-cluster/templates/rbac/_rbac.tpl @@ -1,38 +1,50 @@ -{{- define "base-cluster.rbac.roles" -}} -{{- $roles := dict -}} -{{- $definedRoles := .roles -}} -{{- $definedNamespaces := .namespaces -}} -{{- range $accountName, $account := .accounts -}} - {{- range $roleName, $namespaces := dig "roles" (dict) $account -}} - {{- if not (has $roleName $definedRoles) -}} - {{- fail (printf "Role '%s' doesn't exist, used in account '%s'" $roleName $accountName ) -}} +{{- define "base-cluster.rbac.preexistingRoles" -}} + {{- $preexistingRoles := list -}} + {{- range $role := (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "").items -}} + {{/* Only allow the default k8s ClusterRoles */}} + {{- if eq (dig "metadata" "labels" "kubernetes.io/bootstrapping" "" $role) "rbac-defaults" -}} + {{- $preexistingRoles = append $preexistingRoles $role.metadata.name -}} {{- end -}} + {{- end -}} + {{- toYaml $preexistingRoles -}} +{{- end -}} - {{- $existingRole := dig $roleName (dict) $roles -}} - {{- $namespaceMapping := dig "namespaceMapping" (dict) $existingRole -}} - {{- range $roleNamespace := $namespaces -}} - {{- if not (has $roleNamespace $definedNamespaces) -}} - {{- fail (printf "Role '%s' wants to be in the undefined namespace '%s'" $roleName $roleNamespace) -}} +{{- define "base-cluster.rbac.roles" -}} + {{- $roles := dict -}} + {{- $definedRoles := .roles -}} + {{- $preexistingRoles := include "base-cluster.rbac.preexistingRoles" (dict) | fromYamlArray -}} + {{- $definedNamespaces := .namespaces -}} + {{- range $accountName, $account := .accounts -}} + {{- range $roleName, $namespaces := dig "roles" (dict) $account -}} + {{- if and (not (has $roleName $definedRoles)) (not (has $roleName $preexistingRoles)) -}} + {{- fail (printf "Role '%s' doesn't exist, used in account '%s'" $roleName $accountName ) -}} {{- end -}} - {{- $existingNamespace := dig $roleNamespace (list) $namespaceMapping -}} - {{- $existingNamespace = append $existingNamespace $accountName -}} - {{- $namespaceMapping = set $namespaceMapping $roleNamespace $existingNamespace -}} - {{- end -}} - {{- $existingRole = set $existingRole "namespaceMapping" $namespaceMapping -}} - {{- $roles = set $roles $roleName $existingRole -}} - {{- end -}} - {{- range $roleName := dig "clusterRoles" (list) $account -}} - {{- if not (has $roleName $definedRoles) -}} - {{- fail (printf "Role '%s' doesn't exist, used in account '%s'" $roleName $accountName ) -}} + {{- $existingRole := dig $roleName (dict) $roles -}} + {{- $namespaceMapping := dig "namespaceMapping" (dict) $existingRole -}} + {{- range $roleNamespace := $namespaces -}} + {{- if not (has $roleNamespace $definedNamespaces) -}} + {{- fail (printf "Role '%s' wants to be in the undefined namespace '%s'" $roleName $roleNamespace) -}} + {{- end -}} + + {{- $existingNamespace := dig $roleNamespace (list) $namespaceMapping -}} + {{- $existingNamespace = append $existingNamespace $accountName -}} + {{- $namespaceMapping = set $namespaceMapping $roleNamespace $existingNamespace -}} {{- end -}} + {{- $existingRole = set $existingRole "namespaceMapping" $namespaceMapping -}} + {{- $roles = set $roles $roleName $existingRole -}} + {{- end -}} + {{- range $roleName := dig "clusterRoles" (list) $account -}} + {{- if not (has $roleName $definedRoles) -}} + {{- fail (printf "Role '%s' doesn't exist, used in account '%s'" $roleName $accountName ) -}} + {{- end -}} - {{- $existingRole := dig $roleName (dict) $roles -}} - {{- $clusterMapping := dig "clusterMapping" (list) $existingRole -}} - {{- $clusterMapping = append $clusterMapping $accountName -}} - {{- $existingRole = set $existingRole "clusterMapping" $clusterMapping -}} - {{- $roles = set $roles $roleName $existingRole -}} + {{- $existingRole := dig $roleName (dict) $roles -}} + {{- $clusterMapping := dig "clusterMapping" (list) $existingRole -}} + {{- $clusterMapping = append $clusterMapping $accountName -}} + {{- $existingRole = set $existingRole "clusterMapping" $clusterMapping -}} + {{- $roles = set $roles $roleName $existingRole -}} + {{- end -}} {{- end -}} -{{- end -}} -{{- toYaml $roles -}} + {{- toYaml $roles -}} {{- end -}} diff --git a/charts/base-cluster/templates/rbac/roleBindings.yaml b/charts/base-cluster/templates/rbac/roleBindings.yaml index b2fc3e96d..a49fe51cf 100644 --- a/charts/base-cluster/templates/rbac/roleBindings.yaml +++ b/charts/base-cluster/templates/rbac/roleBindings.yaml @@ -1,9 +1,10 @@ {{- $roles := include "base-cluster.rbac.roles" (dict "accounts" .Values.rbac.accounts "roles" (.Values.rbac.roles | keys) "namespaces" (include "base-cluster.enabled-namespaces" . | fromYaml | keys)) | fromYaml -}} +{{- $definedRoles := .Values.rbac.roles | keys -}} {{- range $roleName, $roleMapping := $roles -}} {{- $clusterMapping := dig "clusterMapping" (dict) $roleMapping -}} {{- $namespaceMapping := dig "namespaceMapping" (dict) $roleMapping -}} - {{- $roleFullName := printf "%s-%s" (include "common.names.fullname" $) $roleName -}} + {{- $roleFullName := has $roleName $definedRoles | ternary (printf "%s-%s" (include "common.names.fullname" $) $roleName) $roleName -}} {{- range $namespace, $accounts := $namespaceMapping }} --- apiVersion: rbac.authorization.k8s.io/v1 @@ -43,4 +44,4 @@ roleRef: kind: ClusterRole name: {{ $roleFullName }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/charts/base-cluster/templates/rbac/roles.yaml b/charts/base-cluster/templates/rbac/roles.yaml index 6daa64111..ff5eec731 100644 --- a/charts/base-cluster/templates/rbac/roles.yaml +++ b/charts/base-cluster/templates/rbac/roles.yaml @@ -1,8 +1,12 @@ +{{- $preExistingRoles := include "base-cluster.rbac.preexistingRoles" (dict) | fromYamlArray -}} {{- $usedRoles := include "base-cluster.rbac.roles" (dict "accounts" .Values.rbac.accounts "roles" (.Values.rbac.roles | keys) "namespaces" (include "base-cluster.enabled-namespaces" . | fromYaml | keys)) | fromYaml -}} {{- range $name, $spec := .Values.rbac.roles -}} {{- if not (hasKey $usedRoles $name) -}} {{- fail (printf "Role '%s' is not used by any account" $name) -}} + {{- end -}} + {{- if has $name $preExistingRoles -}} + {{- fail (printf "Role '%s' clashes with preexisting ClusterRole" $name) -}} {{- end }} --- apiVersion: rbac.authorization.k8s.io/v1