This commit is contained in:
Stavros kois
2023-02-02 19:49:53 +02:00
parent 122ad09fc5
commit 0efb05a1b0
13 changed files with 1064 additions and 3 deletions

View File

@@ -0,0 +1,250 @@
suite: rbac data test
templates:
- common.yaml
tests:
- it: should pass with rules and subjects added with tpl and primary rbac/sa
set:
some_verb: list
some_group: apps
some_resource: deployments
some_kind: some-kind
some_name: some-name
some_api_group: rbac.authorization.k8s.io
serviceAccount:
my-sa:
enabled: true
primary: true
my-other-sa:
enabled: true
primary: false
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- "{{ .Values.some_group }}"
resources:
- "{{ .Values.some_resource }}"
verbs:
- "{{ .Values.some_verb }}"
subjects:
- kind: a-kind
name: a-name
apiGroup: rbac.authorization.k8s.io
- kind: "{{ .Values.some_kind }}"
name: "{{ .Values.some_name }}"
apiGroup: "{{ .Values.some_api_group }}"
asserts:
- documentIndex: &roleDoc 2
isKind:
of: Role
- documentIndex: *roleDoc
equal:
path: metadata.name
value: release-name-common-test
- documentIndex: *roleDoc
equal:
path: rules
value:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resources:
- deployments
verbs:
- list
- documentIndex: &roleBinding 3
isKind:
of: RoleBinding
- documentIndex: *roleBinding
equal:
path: metadata.name
value: release-name-common-test
- documentIndex: *roleBinding
equal:
path: subjects
value:
- kind: ServiceAccount
name: release-name-common-test
namespace: NAMESPACE
- kind: a-kind
name: a-name
apiGroup: rbac.authorization.k8s.io
- kind: some-kind
name: some-name
apiGroup: rbac.authorization.k8s.io
- it: should pass with rules and subjects added with tpl and allSA on clusterWide
set:
some_verb: list
some_group: apps
some_resource: deployments
some_kind: some-kind
some_name: some-name
some_api_group: rbac.authorization.k8s.io
serviceAccount:
my-sa:
enabled: true
primary: true
my-other-sa:
enabled: true
primary: false
rbac:
z-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
my-rbac2:
enabled: true
clusterWide: true
allServiceAccounts: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- "{{ .Values.some_group }}"
resources:
- "{{ .Values.some_resource }}"
verbs:
- "{{ .Values.some_verb }}"
subjects:
- kind: a-kind
name: a-name
apiGroup: rbac.authorization.k8s.io
- kind: "{{ .Values.some_kind }}"
name: "{{ .Values.some_name }}"
apiGroup: "{{ .Values.some_api_group }}"
asserts:
- documentIndex: &clusterRoleDoc 2
isKind:
of: ClusterRole
- documentIndex: *clusterRoleDoc
equal:
path: metadata.name
value: release-name-common-test-my-rbac2
- documentIndex: *clusterRoleDoc
equal:
path: rules
value:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resources:
- deployments
verbs:
- list
- documentIndex: &clusterRoleBinding 3
isKind:
of: ClusterRoleBinding
- documentIndex: *clusterRoleBinding
equal:
path: metadata.name
value: release-name-common-test-my-rbac2
- documentIndex: *clusterRoleBinding
equal:
path: subjects
value:
- kind: ServiceAccount
name: release-name-common-test-my-other-sa
namespace: NAMESPACE
- kind: ServiceAccount
name: release-name-common-test
namespace: NAMESPACE
- apiGroup: rbac.authorization.k8s.io
kind: a-kind
name: a-name
- apiGroup: rbac.authorization.k8s.io
kind: some-kind
name: some-name
- it: should pass with serviceAccount selector
set:
serviceAccount:
my-sa:
enabled: true
primary: true
my-other-sa:
enabled: true
primary: false
rbac:
z-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
my-rbac3:
enabled: true
serviceAccounts:
- my-other-sa
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
asserts:
- documentIndex: &roleDoc 2
isKind:
of: Role
- documentIndex: *roleDoc
equal:
path: metadata.name
value: release-name-common-test-my-rbac3
- documentIndex: *roleDoc
equal:
path: rules
value:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- documentIndex: &roleBinding 3
isKind:
of: RoleBinding
- documentIndex: *roleBinding
equal:
path: metadata.name
value: release-name-common-test-my-rbac3
- documentIndex: *roleBinding
equal:
path: subjects
value:
- kind: ServiceAccount
name: release-name-common-test-my-other-sa
namespace: NAMESPACE

View File

@@ -0,0 +1,163 @@
suite: rbac metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
tests:
- it: should pass with rbac created with labels and annotations
set:
label1: label1
label2: global_label2
annotation1: annotation1
annotation2: global_annotation2
global:
labels:
g_label1: global_label1
g_label2: "{{ .Values.label2 }}"
annotations:
g_annotation1: global_annotation1
g_annotation2: "{{ .Values.annotation2 }}"
serviceAccount:
my-sa1:
enabled: true
primary: true
rbac:
my-rbac1:
enabled: true
primary: true
labels:
label1: "{{ .Values.label1 }}"
label2: label2
annotations:
annotation1: "{{ .Values.annotation1 }}"
annotation2: annotation2
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
my-rbac2:
enabled: true
primary: false
clusterWide: true
allServiceAccounts: true
labels:
label1: "{{ .Values.label1 }}"
label2: label2
annotations:
annotation1: "{{ .Values.annotation1 }}"
annotation2: annotation2
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
asserts:
- documentIndex: &roleDoc 1
isKind:
of: Role
- documentIndex: *roleDoc
equal:
path: metadata.annotations
value:
annotation1: annotation1
annotation2: annotation2
g_annotation1: global_annotation1
g_annotation2: global_annotation2
- documentIndex: *roleDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: release-name
helm-revision: 0
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
- documentIndex: &roleBindingDoc 2
isKind:
of: RoleBinding
- documentIndex: *roleBindingDoc
equal:
path: metadata.annotations
value:
annotation1: annotation1
annotation2: annotation2
g_annotation1: global_annotation1
g_annotation2: global_annotation2
- documentIndex: *roleBindingDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: release-name
helm-revision: 0
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
- documentIndex: &clusterRoleDoc 3
isKind:
of: ClusterRole
- documentIndex: *clusterRoleDoc
equal:
path: metadata.annotations
value:
annotation1: annotation1
annotation2: annotation2
g_annotation1: global_annotation1
g_annotation2: global_annotation2
- documentIndex: *clusterRoleDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: release-name
helm-revision: 0
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
- documentIndex: &clusterRoleBindingDoc 4
isKind:
of: ClusterRoleBinding
- documentIndex: *clusterRoleBindingDoc
equal:
path: metadata.annotations
value:
annotation1: annotation1
annotation2: annotation2
g_annotation1: global_annotation1
g_annotation2: global_annotation2
- documentIndex: *clusterRoleBindingDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: release-name
helm-revision: 0
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2

View File

@@ -0,0 +1,105 @@
suite: rbac name test
templates:
- common.yaml
tests:
- it: should generate correct name
set:
serviceAccount:
my-sa:
enabled: true
primary: true
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
my-rbac2:
enabled: true
clusterWide: true
allServiceAccounts: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
my-rbac3:
enabled: true
allServiceAccounts: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
asserts:
- documentIndex: &roleDoc 1
isKind:
of: Role
- documentIndex: *roleDoc
isAPIVersion:
of: rbac.authorization.k8s.io/v1
- documentIndex: *roleDoc
equal:
path: metadata.name
value: release-name-common-test
- documentIndex: &roleBindingDoc 2
isKind:
of: RoleBinding
- documentIndex: *roleBindingDoc
isAPIVersion:
of: rbac.authorization.k8s.io/v1
- documentIndex: *roleBindingDoc
equal:
path: metadata.name
value: release-name-common-test
- documentIndex: &clusterRoleDoc 3
isKind:
of: ClusterRole
- documentIndex: *clusterRoleDoc
isAPIVersion:
of: rbac.authorization.k8s.io/v1
- documentIndex: *clusterRoleDoc
equal:
path: metadata.name
value: release-name-common-test-my-rbac2
- documentIndex: &clusterRoleBindingDoc 4
isKind:
of: ClusterRoleBinding
- documentIndex: *clusterRoleBindingDoc
isAPIVersion:
of: rbac.authorization.k8s.io/v1
- documentIndex: *clusterRoleBindingDoc
equal:
path: metadata.name
value: release-name-common-test-my-rbac2
- documentIndex: &otherRoleDoc 5
isKind:
of: Role
- documentIndex: *otherRoleDoc
isAPIVersion:
of: rbac.authorization.k8s.io/v1
- documentIndex: *otherRoleDoc
equal:
path: metadata.name
value: release-name-common-test-my-rbac3
- documentIndex: &otherRoleBindingDoc 6
isKind:
of: RoleBinding
- documentIndex: *otherRoleBindingDoc
isAPIVersion:
of: rbac.authorization.k8s.io/v1
- documentIndex: *otherRoleBindingDoc
equal:
path: metadata.name
value: release-name-common-test-my-rbac3

View File

@@ -0,0 +1,250 @@
suite: rbac validation test
templates:
- common.yaml
tests:
- it: should fail with name longer than 63 characters
set:
rbac:
zmy-rbac:
enabled: true
primary: true
my-rbac-has-super-long-name-that-is-longer-than-63-characters-too-bad:
enabled: true
primary: false
asserts:
- failedTemplate:
errorMessage: Name [release-name-common-test-my-rbac-has-super-long-name-that-is-longer-than-63-characters-too-bad] is not valid. Must start and end with an alphanumeric character. It can contain '-'. And must be at most 63 characters.
- it: should fail with name starting with underscore
set:
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
_my-rbac2:
enabled: true
primary: false
asserts:
- failedTemplate:
errorMessage: Name [release-name-common-test-_my-rbac2] is not valid. Must start and end with an alphanumeric character. It can contain '-'. And must be at most 63 characters.
- it: should fail with labels not a dict
set:
rbac:
my-rbac:
enabled: true
primary: true
labels: "not a dict"
asserts:
- failedTemplate:
errorMessage: RBAC - Expected <labels> to be a dictionary, but got [string]
- it: should fail with annotations not a dict
set:
rbac:
my-rbac:
enabled: true
primary: true
annotations: "not a dict"
asserts:
- failedTemplate:
errorMessage: RBAC - Expected <annotations> to be a dictionary, but got [string]
- it: should fail with more than 1 primary rbac
set:
rbac:
my-rbac:
enabled: true
primary: true
my-rbac2:
enabled: true
primary: true
asserts:
- failedTemplate:
errorMessage: RBAC - Only one rbac can be primary
- it: should fail without any primary on enabled rbac
set:
rbac:
my-rbac:
enabled: true
primary: false
my-rbac2:
enabled: true
primary: false
asserts:
- failedTemplate:
errorMessage: RBAC - At least one enabled rbac must be primary
- it: should fail without rules in rbac
set:
rbac:
my-rbac:
enabled: true
primary: true
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty <rbac.rules>
- it: should fail without apiGroups in rules in rbac
set:
rbac:
my-rbac:
enabled: true
primary: true
rules:
- resources:
- pods
verbs:
- get
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty <rbac.rules.apiGroups>
- it: should fail without resources in rules in rbac
set:
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
verbs:
- get
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty <rbac.rules.resources>
- it: should fail without verbs in rules in rbac
set:
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty <rbac.rules.verbs>
- it: should fail with empty entry in resources in rules in rbac
set:
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
- ""
verbs:
- get
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty entry in <rbac.rules.resources>
- it: should fail with empty entry in verbs in rules in rbac
set:
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- ""
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty entry in <rbac.rules.verbs>
- it: should fail with empty kind in subjects in rbac
set:
serviceAccount:
my-service-account:
enabled: true
primary: true
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
subjects:
- kind: ""
name: my-name
apiGroup: my-apiGroup
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty <rbac.subjects.kind>
- it: should fail with empty name in subjects in rbac
set:
serviceAccount:
my-service-account:
enabled: true
primary: true
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
subjects:
- kind: my-kind
name: ""
apiGroup: my-apiGroup
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty <rbac.subjects.name>
- it: should fail with empty apiGroup in subjects in rbac
set:
serviceAccount:
my-service-account:
enabled: true
primary: true
rbac:
my-rbac:
enabled: true
primary: true
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
subjects:
- kind: my-kind
name: my-name
apiGroup: ""
asserts:
- failedTemplate:
errorMessage: RBAC - Expected non-empty <rbac.subjects.apiGroup>

View File

@@ -5,13 +5,13 @@ tests:
- it: should generate correct name
set:
serviceAccount:
my-sa:
enabled: true
primary: true
my-sa1:
enabled: true
my-sa2:
enabled: true
main:
enabled: true
primary: true
asserts:
- documentIndex: &primaryServiceAccount 0
isKind:

View File

@@ -0,0 +1,64 @@
{{/* RBAC Class */}}
{{/* Call this template:
{{ include "ix.v1.common.class.rbac" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the template. It is used to access the global context.
objectData:
name: The name of the rbac.
labels: The labels of the rbac.
annotations: The annotations of the rbac.
clusterWide: Whether the rbac is cluster wide or not.
rules: The rules of the rbac.
subjects: The subjects of the rbac.
*/}}
{{- define "ix.v1.common.class.rbac" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ ternary "ClusterRole" "Role" $objectData.clusterWide }}
metadata:
name: {{ $objectData.name }}
{{- if not $objectData.clusterWide }}
namespace: {{ $rootCtx.Release.Namespace }}
{{- end }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "ix.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "ix.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "ix.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "ix.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
rules:
{{- include "ix.v1.common.lib.rbac.rules" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ ternary "ClusterRoleBinding" "RoleBinding" $objectData.clusterWide }}
metadata:
name: {{ $objectData.name }}
{{- if not $objectData.clusterWide }}
namespace: {{ $rootCtx.Release.Namespace }}
{{- end }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "ix.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "ix.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "ix.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "ix.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: {{ ternary "ClusterRole" "Role" $objectData.clusterWide }}
name: {{ $objectData.name }}
subjects:
{{- include "ix.v1.common.lib.rbac.serviceAccount" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
{{- include "ix.v1.common.lib.rbac.subjects" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
{{- end -}}

View File

@@ -0,0 +1,52 @@
{{/* Returns Service Account List for rbac */}}
{{/* Call this template:
{{ include "ix.v1.common.lib.rbac.serviceAccount" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the template. It is used to access the global context.
objectData: The object data to be used to render the RBAC.
*/}}
{{/* Parses service accounts, and checks if RBAC have selected any of them */}}
{{- define "ix.v1.common.lib.rbac.serviceAccount" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $serviceAccounts := list -}}
{{- range $name, $serviceAccount := $rootCtx.Values.serviceAccount -}}
{{- $saName := include "ix.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- if $serviceAccount.enabled -}}
{{- if not $serviceAccount.primary -}}
{{- $saName = (printf "%s-%s" (include "ix.v1.common.lib.chart.names.fullname" $rootCtx) $name) -}}
{{- end -}}
{{/* If allServiceAccounts is true */}}
{{- if $objectData.allServiceAccounts -}}
{{- $serviceAccounts = mustAppend $serviceAccounts $saName -}}
{{/* Else if serviceAccounts is a list */}}
{{- else if (kindIs "slice" $objectData.serviceAccounts) -}}
{{- if (mustHas $name $objectData.serviceAccounts) -}}
{{- $serviceAccounts = mustAppend $serviceAccounts $saName -}}
{{- end -}}
{{/* If not "allServiceAccounts" or "serviceAccounts", assign the primary service account to rbac */}}
{{- else if $serviceAccount.primary -}}
{{- if $objectData.primary -}}
{{- $serviceAccounts = mustAppend $serviceAccounts $saName -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $serviceAccounts -}}
{{- fail "RBAC - Expected at least one serviceAccount to be assigned. Assign one using [allServiceAccounts (boolean), serviceAccounts (list)]" -}}
{{- end -}}
{{- range $serviceAccounts }}
- kind: ServiceAccount
name: {{ . }}
namespace: {{ $rootCtx.Release.Namespace }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,50 @@
{{/* Returns Rules for rbac */}}
{{/* Call this template:
{{ include "ix.v1.common.lib.rbac.rules" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the template. It is used to access the global context.
objectData: The object data to be used to render the RBAC.
*/}}
{{/* Parses service accounts, and checks if RBAC have selected any of them */}}
{{- define "ix.v1.common.lib.rbac.rules" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.rules -}}
{{- fail "RBAC - Expected non-empty <rbac.rules>" -}}
{{- end -}}
{{- range $objectData.rules -}}
{{- if not .apiGroups -}}
{{- fail "RBAC - Expected non-empty <rbac.rules.apiGroups>" -}}
{{- end -}}
{{- if not .resources -}}
{{- fail "RBAC - Expected non-empty <rbac.rules.resources>" -}}
{{- end -}}
{{- if not .verbs -}}
{{- fail "RBAC - Expected non-empty <rbac.rules.verbs>" -}}
{{- end -}}
{{- /* apiGroups */}}
- apiGroups:
{{- range .apiGroups }}
- {{ tpl . $rootCtx | quote }}
{{- end -}}
{{- /* resources */}}
resources:
{{- range .resources -}}
{{- if not . -}}
{{- fail "RBAC - Expected non-empty entry in <rbac.rules.resources>" -}}
{{- end }}
- {{ tpl . $rootCtx | quote }}
{{- end -}}
{{- /* verbs */}}
verbs:
{{- range .verbs -}}
{{- if not . -}}
{{- fail "RBAC - Expected non-empty entry in <rbac.rules.verbs>" -}}
{{- end }}
- {{ tpl . $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,17 @@
{{/* Returns Subjects for rbac */}}
{{/* Call this template:
{{ include "ix.v1.common.lib.rbac.subjects" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the template. It is used to access the global context.
objectData: The object data to be used to render the RBAC.
*/}}
{{/* Parses service accounts, and checks if RBAC have selected any of them */}}
{{- define "ix.v1.common.lib.rbac.subjects" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- range $objectData.subjects }}
- kind: {{ tpl (required "RBAC - Expected non-empty <rbac.subjects.kind>" .kind) $rootCtx | quote }}
name: {{ tpl (required "RBAC - Expected non-empty <rbac.subjects.name>" .name) $rootCtx | quote }}
apiGroup: {{ tpl (required "RBAC - Expected non-empty <rbac.subjects.apiGroup>" .apiGroup) $rootCtx | quote }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,63 @@
{{/* RBAC Validation */}}
{{/* Call this template:
{{ include "ix.v1.common.lib.rbac.validation" (dict "objectData" $objectData) -}}
objectData:
labels: The labels of the rbac.
annotations: The annotations of the rbac.
data: The data of the rbac.
*/}}
{{- define "ix.v1.common.lib.rbac.validation" -}}
{{- $objectData := .objectData -}}
{{- if and $objectData.labels (not (kindIs "map" $objectData.labels)) -}}
{{- fail (printf "RBAC - Expected <labels> to be a dictionary, but got [%v]" (kindOf $objectData.labels)) -}}
{{- end -}}
{{- if and $objectData.annotations (not (kindIs "map" $objectData.annotations)) -}}
{{- fail (printf "RBAC - Expected <annotations> to be a dictionary, but got [%v]" (kindOf $objectData.annotations)) -}}
{{- end -}}
{{- end -}}
{{/* RBAC Primary Validation */}}
{{/* Call this template:
{{ include "ix.v1.common.lib.rbac.primaryValidation" (dict "objectData" $objectData) -}}
objectData:
labels: The labels of the rbac.
annotations: The annotations of the rbac.
*/}}
{{- define "ix.v1.common.lib.rbac.primaryValidation" -}}
{{/* Initialize values */}}
{{- $hasPrimary := false -}}
{{- $hasEnabled := false -}}
{{- range $name, $rbac := .Values.rbac -}}
{{/* If rbac is enabled */}}
{{- if $rbac.enabled -}}
{{- $hasEnabled = true -}}
{{/* And rbac is primary */}}
{{- if and (hasKey $rbac "primary") ($rbac.primary) -}}
{{/* Fail if there is already a primary rbac */}}
{{- if $hasPrimary -}}
{{- fail "RBAC - Only one rbac can be primary" -}}
{{- end -}}
{{- $hasPrimary = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Require at least one primary rbac, if any enabled */}}
{{- if and $hasEnabled (not $hasPrimary) -}}
{{- fail "RBAC - At least one enabled rbac must be primary" -}}
{{- end -}}
{{- end -}}

View File

@@ -13,6 +13,9 @@
{{/* Render Service Accounts(s) */}}
{{- include "ix.v1.common.spawner.serviceAccount" . | nindent 0 -}}
{{/* Render RBAC(s) */}}
{{- include "ix.v1.common.spawner.rbac" . | nindent 0 -}}
{{/* Render Workload(s) */}}
{{- include "ix.v1.common.spawner.workload" . | nindent 0 -}}

View File

@@ -0,0 +1,43 @@
{{/* RBAC Spawner */}}
{{/* Call this template:
{{ include "ix.v1.common.spawner.rbac" $ -}}
*/}}
{{- define "ix.v1.common.spawner.rbac" -}}
{{/* Primary validation for enabled rbacs. */}}
{{- include "ix.v1.common.lib.rbac.primaryValidation" $ -}}
{{- range $name, $rbac := .Values.rbac -}}
{{- if $rbac.enabled -}}
{{/* Create a copy of the configmap */}}
{{- $objectData := (mustDeepCopy $rbac) -}}
{{- $objectName := include "ix.v1.common.lib.chart.names.fullname" $ -}}
{{- if not $objectData.primary -}}
{{- $objectName = (printf "%s-%s" (include "ix.v1.common.lib.chart.names.fullname" $) $name) -}}
{{- end -}}
{{/* Perform validations */}}
{{- include "ix.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}}
{{- include "ix.v1.common.lib.rbac.validation" (dict "objectData" $objectData) -}}
{{/* Set the name of the rbac */}}
{{- $_ := set $objectData "name" $objectName -}}
{{- $_ := set $objectData "shortName" $name -}}
{{/* If clusteWide key does not exist, assume false */}}
{{- if not (hasKey $objectData "clusterWide") -}}
{{- $_ := set $objectData "clusterWide" false -}}
{{- end -}}
{{/* Call class to create the object */}}
{{- include "ix.v1.common.class.rbac" (dict "rootCtx" $ "objectData" $objectData) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -26,6 +26,7 @@
{{/* Set the name of the service account */}}
{{- $_ := set $objectData "name" $objectName -}}
{{- $_ := set $objectData "shortName" $name -}}
{{/* Call class to create the object */}}
{{- include "ix.v1.common.class.serviceAccount" (dict "rootCtx" $ "objectData" $objectData) -}}