From a3b24e4bf3f7256ac5a168d74830ddd79ba5f8d9 Mon Sep 17 00:00:00 2001 From: Chris Werner Rau Date: Mon, 11 Nov 2024 12:47:21 +0100 Subject: [PATCH] feat(base-cluster/rbac)!: allow to use the k8s default ClusterRoles (#1230) 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