diff --git a/README.md b/README.md index 6db3f445..dcd36954 100644 --- a/README.md +++ b/README.md @@ -213,12 +213,14 @@ helm delete --namespace test my-application | Key | Type | Default | Description | |-----|------|---------|-------------| -| rbac.enabled | bool | `true` | Enable RBAC. | -| rbac.serviceAccount.enabled | bool | `false` | Deploy Service Account. | -| rbac.serviceAccount.name | string | `{{ include "application.name" $ }}` | Service Account Name. | -| rbac.serviceAccount.additionalLabels | object | `nil` | Additional labels for Service Account. | -| rbac.serviceAccount.annotations | object | `nil` | Annotations for Service Account. | +| rbac.enabled | bool | `true` | Enable RBAC. This fields also controls the `automountServiceAccountToken` field in the pod spec. | +| rbac.serviceAccount.create | bool | `false` | Specifies whether to create a dedicated service account. If set to `true`, a new service account will be created. | +| rbac.serviceAccount.name | string | `""` | The name of the service account. Behavior based on its value and `rbac.serviceAccount.create`: If `rbac.serviceAccount.create` is `false` and `name` is empty, the default service account ("default") is used. If `rbac.serviceAccount.create` is `false` and `name` is set, the provided name is used. If `rbac.serviceAccount.create` is `true` and `name` is empty, a name is auto-generated using the fullname template. If `rbac.serviceAccount.create` is `true` and `name` is set, the provided name is used for creation. | +| rbac.serviceAccount.additionalLabels | object | `nil` | Additional labels for Service Account. If `rbac.serviceAccount.create` is set to true, these labels are appended to the service account. | +| rbac.serviceAccount.annotations | object | `nil` | Annotations for Service Account. If `rbac.serviceAccount.create` is set to true, these annotations are appended to the service account. | | rbac.roles | list | `nil` | Namespaced Roles. | +| rbac.additionalLabels | object | `nil` | Additional labels for the Role and RoleBinding resources. | +| rbac.annotations | object | `nil` | Annotations for the Role and RoleBinding resources. | ### ConfigMap Parameters diff --git a/application/templates/_helpers.tpl b/application/templates/_helpers.tpl index d678c846..9dfb23de 100644 --- a/application/templates/_helpers.tpl +++ b/application/templates/_helpers.tpl @@ -68,3 +68,18 @@ reference: kind: Route name: {{ include "application.name" . }} {{- end }} + +{{/* +Get the name of the service account to use. +If the service account is set to be created, return the service account name or a default name. +If the service account is not set to be created and a name is provided, return the provided name; +otherwise, return the default namespace service account. +*/}} +{{- define "application.serviceAccountName" }} + {{- $saName := .Values.rbac.serviceAccount.name }} + {{- if .Values.rbac.serviceAccount.create }} + {{- empty $saName | ternary (include "application.name" .) (quote $saName) }} + {{- else }} + {{- empty $saName | ternary "default" (quote $saName) }} + {{- end }} +{{- end }} diff --git a/application/templates/cronjob.yaml b/application/templates/cronjob.yaml index 7b35cb65..77671c32 100644 --- a/application/templates/cronjob.yaml +++ b/application/templates/cronjob.yaml @@ -56,13 +56,8 @@ spec: annotations: {{ toYaml . | nindent 12 }} {{- end }} spec: - {{- if $.Values.rbac.enabled }} - {{- if $.Values.rbac.serviceAccount.name }} - serviceAccountName: {{ $.Values.rbac.serviceAccount.name }} - {{- else }} - serviceAccountName: {{ template "application.name" $ }} - {{- end }} - {{- end }} + automountServiceAccountToken: {{ $.Values.rbac.enabled }} + serviceAccountName: {{ include "application.serviceAccountName" $ }} containers: - name: {{ $name }} {{- $image := required (print "Undefined image repo for container '" $name "'") $job.image.repository }} diff --git a/application/templates/deployment.yaml b/application/templates/deployment.yaml index f966b54e..54d5bd16 100644 --- a/application/templates/deployment.yaml +++ b/application/templates/deployment.yaml @@ -74,6 +74,8 @@ spec: ] {{- end }} spec: + automountServiceAccountToken: {{ $.Values.rbac.enabled }} + serviceAccountName: {{ include "application.serviceAccountName" $ }} {{- with .Values.deployment.hostAliases }} hostAliases: {{- toYaml . | nindent 6 }} {{- end }} @@ -310,13 +312,6 @@ spec: {{- end }} {{- end }} {{- end }} - {{- if .Values.rbac.serviceAccount.enabled }} - {{- if .Values.rbac.serviceAccount.name }} - serviceAccountName: {{ .Values.rbac.serviceAccount.name }} - {{- else }} - serviceAccountName: {{ template "application.name" $ }} - {{- end }} - {{- end }} {{- if .Values.deployment.hostNetwork }} hostNetwork: {{ .Values.deployment.hostNetwork }} {{- end }} diff --git a/application/templates/job.yaml b/application/templates/job.yaml index fd62305f..74e7fc42 100644 --- a/application/templates/job.yaml +++ b/application/templates/job.yaml @@ -36,13 +36,8 @@ spec: annotations: {{ toYaml . | nindent 8 }} {{- end }} spec: - {{- if $.Values.rbac.enabled }} - {{- if $.Values.rbac.serviceAccount.name }} - serviceAccountName: {{ $.Values.rbac.serviceAccount.name }} - {{- else }} - serviceAccountName: {{ template "application.name" $ }} - {{- end }} - {{- end }} + automountServiceAccountToken: {{ $.Values.rbac.enabled }} + serviceAccountName: {{ include "application.serviceAccountName" $ }} containers: - name: {{ $name }} {{- $image := required (print "Undefined image repo for container '" $name "'") $job.image.repository }} @@ -101,7 +96,7 @@ spec: restartPolicy: OnFailure {{ end }} {{- with $job.imagePullSecrets}} - imagePullSecrets: + imagePullSecrets: {{ toYaml . | indent 8 }} {{ end }} {{- if $job.dnsConfig }} diff --git a/application/templates/rolebinding.yaml b/application/templates/rolebinding.yaml index d32a4acd..7fc96968 100644 --- a/application/templates/rolebinding.yaml +++ b/application/templates/rolebinding.yaml @@ -21,11 +21,7 @@ roleRef: name: {{ template "application.name" $ }}-role-{{ .name }} subjects: - kind: ServiceAccount - {{- if $.Values.rbac.serviceAccount.name }} - name: {{ $.Values.rbac.serviceAccount.name }} - {{- else }} - name: {{ template "application.name" $ }} - {{- end }} + name: {{ include "application.serviceAccountName" $ }} namespace: {{ $.Release.Namespace }} {{- end }} {{- end }} diff --git a/application/templates/serviceaccount.yaml b/application/templates/serviceaccount.yaml index 3c361ddb..0715e7fd 100644 --- a/application/templates/serviceaccount.yaml +++ b/application/templates/serviceaccount.yaml @@ -1,9 +1,9 @@ -{{- if and .Values.rbac.enabled .Values.rbac.serviceAccount.enabled }} +{{- if and .Values.rbac.enabled .Values.rbac.serviceAccount.create }} --- apiVersion: v1 kind: ServiceAccount metadata: - name: {{ default (include "application.name" .) .Values.rbac.serviceAccount.name }} + name: {{ include "application.serviceAccountName" . }} namespace: {{ template "application.namespace" . }} labels: {{- include "application.labels" $ | nindent 4 }} diff --git a/application/tests/cronjob_test.yaml b/application/tests/cronjob_test.yaml index e9048ae5..5112a218 100644 --- a/application/tests/cronjob_test.yaml +++ b/application/tests/cronjob_test.yaml @@ -115,3 +115,80 @@ tests: path: spec.jobTemplate.spec.template.metadata.annotations value: helm.sh/hook: "pre-install,pre-upgrade" + + - it: yields default service account name when create is disabled and no existing service account name is given + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + rbac.serviceAccount.create: false + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.serviceAccountName + value: default + + - it: uses service account name override when present + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + rbac.serviceAccount.create: true + rbac.serviceAccount.name: example-sa + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.serviceAccountName + value: example-sa + + - it: uses a generated service account name when not given + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + applicationName: example-app + rbac.serviceAccount.create: true + rbac.serviceAccount.name: "" + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.serviceAccountName + value: example-app + + - it: enables automountServiceAccountToken when RBAC is enabled + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + applicationName: example-app + rbac: + enabled: true + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.automountServiceAccountToken + value: true + + - it: disables automountServiceAccountToken when RBAC is disabled + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + applicationName: example-app + rbac: + enabled: false + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.automountServiceAccountToken + value: false diff --git a/application/tests/deployment_test.yaml b/application/tests/deployment_test.yaml index 40c386e2..3dbfd11d 100644 --- a/application/tests/deployment_test.yaml +++ b/application/tests/deployment_test.yaml @@ -87,16 +87,17 @@ tests: path: spec.template.spec.containers[0].image value: example-image:example-tag@sha256:example-digest - - it: yields empty service account name when disabled + - it: yields default service account name when create is disabled and no existing service account name is given set: - rbac.serviceAccount.enabled: false + rbac.serviceAccount.create: false asserts: - - notExists: + - equal: path: spec.template.spec.serviceAccountName + value: default - it: uses service account name override when present set: - rbac.serviceAccount.enabled: true + rbac.serviceAccount.create: true rbac.serviceAccount.name: example-sa asserts: - equal: @@ -106,13 +107,31 @@ tests: - it: uses a generated service account name when not given set: applicationName: example-app - rbac.serviceAccount.enabled: true + rbac.serviceAccount.create: true rbac.serviceAccount.name: "" asserts: - equal: path: spec.template.spec.serviceAccountName value: example-app + - it: enables automountServiceAccountToken when RBAC is enabled + set: + applicationName: example-app + rbac.enabled: true + asserts: + - equal: + path: spec.template.spec.automountServiceAccountToken + value: true + + - it: disables automountServiceAccountToken when RBAC is disabled + set: + applicationName: example-app + rbac.enabled: false + asserts: + - equal: + path: spec.template.spec.automountServiceAccountToken + value: false + - it: uses grpc probing when set set: applicationName: example-app diff --git a/application/tests/job_test.yaml b/application/tests/job_test.yaml index 465a485e..b215b5b6 100644 --- a/application/tests/job_test.yaml +++ b/application/tests/job_test.yaml @@ -115,3 +115,78 @@ tests: path: spec.template.metadata.annotations value: helm.sh/hook: "pre-install,pre-upgrade" + + - it: yields empty service account name when disabled + set: + job: + enabled: true + jobs: + example: + image: + repository: example-image + rbac.serviceAccount.create: false + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: default + + - it: uses service account name override when present + set: + job: + enabled: true + jobs: + example: + image: + repository: example-image + rbac.serviceAccount.create: true + rbac.serviceAccount.name: example-sa + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: example-sa + + - it: uses a generated service account name when not given + set: + job: + enabled: true + jobs: + example: + image: + repository: example-image + applicationName: example-app + rbac.serviceAccount.create: true + rbac.serviceAccount.name: "" + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: example-app + + - it: enables automountServiceAccountToken when RBAC is enabled + set: + job: + enabled: true + jobs: + example: + image: + repository: example-image + applicationName: example-app + rbac.enabled: true + asserts: + - equal: + path: spec.template.spec.automountServiceAccountToken + value: true + + - it: disables automountServiceAccountToken when RBAC is disabled + set: + job: + enabled: true + jobs: + example: + image: + repository: example-image + applicationName: example-app + rbac.enabled: false + asserts: + - equal: + path: spec.template.spec.automountServiceAccountToken + value: false diff --git a/application/tests/rolebinding_test.yaml b/application/tests/rolebinding_test.yaml index 7e4875eb..9bfbd8e6 100644 --- a/application/tests/rolebinding_test.yaml +++ b/application/tests/rolebinding_test.yaml @@ -121,6 +121,7 @@ tests: roles: - name: example serviceAccount: + create: true name: "" asserts: - equal: diff --git a/application/tests/serviceaccount_test.yaml b/application/tests/serviceaccount_test.yaml index 14e838ce..8579e13f 100644 --- a/application/tests/serviceaccount_test.yaml +++ b/application/tests/serviceaccount_test.yaml @@ -9,7 +9,7 @@ tests: rbac: enabled: false serviceAccount: - enabled: true + create: true asserts: - hasDocuments: count: 0 @@ -19,7 +19,7 @@ tests: rbac: enabled: true serviceAccount: - enabled: false + create: false asserts: - hasDocuments: count: 0 @@ -29,7 +29,7 @@ tests: rbac: enabled: true serviceAccount: - enabled: true + create: true asserts: - hasDocuments: count: 1 @@ -41,7 +41,7 @@ tests: rbac: enabled: true serviceAccount: - enabled: true + create: true additionalLabels: foo: bar test: ing @@ -59,7 +59,7 @@ tests: rbac: enabled: true serviceAccount: - enabled: true + create: true annotations: foo: bar test: ing @@ -76,7 +76,7 @@ tests: rbac: enabled: true serviceAccount: - enabled: true + create: true asserts: - matchRegex: path: metadata.annotations["serviceaccounts.openshift.io/oauth-redirectreference.primary"] @@ -87,7 +87,7 @@ tests: rbac: enabled: true serviceAccount: - enabled: true + create: true name: example-name-that-should-be-used asserts: - equal: diff --git a/application/values-test.yaml b/application/values-test.yaml index 298443c7..63e2a4bc 100644 --- a/application/values-test.yaml +++ b/application/values-test.yaml @@ -273,7 +273,7 @@ service: kubernetes.io/ingress.class: external-ingress ingress.kubernetes.io/rewrite-target: / ingress.kubernetes.io/force-ssl-redirect: "true" - + ports: - port: 8080 name: http @@ -388,7 +388,7 @@ forecastle: # URL of the icon for the custom app icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/stakater-big.png - + # Name of the application to be displayed on the Forecastle Dashboard displayName: "application" @@ -407,7 +407,7 @@ rbac: # Service Account to use by pods serviceAccount: - enabled: true + create: true name: "application" # Additional Labels on service account @@ -705,13 +705,13 @@ externalSecret: #SecretStore defines which SecretStore to use when fetching the secret data secretStore: name: example-secret-store - #kind: SecretStore # or ClusterSecretStore + #kind: SecretStore # or ClusterSecretStore # RefreshInterval is the amount of time before the values reading again from the SecretStore provider refreshInterval: "1m" files: secret-1-name: - #Data defines the connection between the Kubernetes Secret keys and the Provider data + #Data defines the connection between the Kubernetes Secret keys and the Provider data data: example-secret-key: remoteRef: @@ -1323,7 +1323,7 @@ backup: snapshotVolumes: true storageLocation: "dpa-1" ttl: "1h0m0s" - includedResources: + includedResources: - deployments - services - persistentvolumeclaims @@ -1338,7 +1338,7 @@ backup: - resourcequotas - controllerrevisions.apps -job: +job: enabled: true jobs: db-migration: @@ -1348,15 +1348,15 @@ job: helm.sh/hook-delete-policy: "before-hook-creation" imagePullSecrets: - name: nexus-secret - image: + image: repository: docker.io/nginx tag: v1.0.0 - env: + env: KEY: value: VALUE command: ["/bin/bash"] args: ["-c","sleep 5000"] - resources: + resources: requests: memory: 5Gi cpu: 1 diff --git a/application/values.yaml b/application/values.yaml index bbdbb778..3a1d388f 100644 --- a/application/values.yaml +++ b/application/values.yaml @@ -680,22 +680,25 @@ forecastle: networkRestricted: false rbac: - # -- (bool) Enable RBAC. + # -- (bool) Enable RBAC. This fields also controls the `automountServiceAccountToken` field in the pod spec. # @section -- RBAC Parameters enabled: true serviceAccount: - # -- (bool) Deploy Service Account. + # -- (bool) Specifies whether to create a dedicated service account. If set to `true`, a new service account will be created. # @section -- RBAC Parameters - enabled: false - # -- (string) Service Account Name. - # @default -- `{{ include "application.name" $ }}` + create: false + # -- (string) The name of the service account. Behavior based on its value and `rbac.serviceAccount.create`: + # If `rbac.serviceAccount.create` is `false` and `name` is empty, the default service account ("default") is used. + # If `rbac.serviceAccount.create` is `false` and `name` is set, the provided name is used. + # If `rbac.serviceAccount.create` is `true` and `name` is empty, a name is auto-generated using the fullname template. + # If `rbac.serviceAccount.create` is `true` and `name` is set, the provided name is used for creation. # @section -- RBAC Parameters name: "" - # -- (object) Additional labels for Service Account. + # -- (object) Additional labels for Service Account. If `rbac.serviceAccount.create` is set to true, these labels are appended to the service account. # @section -- RBAC Parameters additionalLabels: # key: value - # -- (object) Annotations for Service Account. + # -- (object) Annotations for Service Account. If `rbac.serviceAccount.create` is set to true, these annotations are appended to the service account. # @section -- RBAC Parameters annotations: # key: value @@ -718,6 +721,14 @@ rbac: # - secrets # verbs: # - get + # -- (object) Additional labels for the Role and RoleBinding resources. + # @section -- RBAC Parameters + additionalLabels: + # key: value + # -- (object) Annotations for the Role and RoleBinding resources. + # @section -- RBAC Parameters + annotations: + # key: value configMap: # -- (bool) Deploy additional ConfigMaps.