mirror of
https://github.com/coder/coder.git
synced 2026-06-05 14:08:20 +00:00
623893708b
This is a feature to create Role & RoleBinding entries on a per namespace basis to support deploying workspaces in separate namespace to where Coder is deployed. The idea behind this is to avoid the creation of custom RBAC entries or the use of ClusterRoles (in order to maintain priciple of least privilege). > If you have used AI to produce some or all of this PR, please ensure you have read our [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING) before submitting. This is a blink assisted PR. Example `helm template` without `coder.serviceAccount.workspaceNamespaces` enabled (existing behaviour as of current release) is below. Outcome = 1 x SA, 1 x Role, 1 x RoleBinding, all in the coder (`.Release.Namespace`) namespace. ``` ➜ coder git:(feat/helm_namespace_rbac_improvements) ✗ helm template -n coder coder . --set coder.image.tag=v2.25.1 --- ... --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: coder-workspace-perms namespace: coder rules: - apiGroups: [""] resources: ["pods"] verbs: - create - delete - deletecollection - get - list - patch - update - watch - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: - create - delete - deletecollection - get - list - patch - update - watch - apiGroups: - apps resources: - deployments verbs: - create - delete - deletecollection - get - list - patch - update - watch --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: "coder" namespace: coder subjects: - kind: ServiceAccount name: "coder" roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: coder-workspace-perms --- ``` Example `helm template` *with* `coder.serviceAccount.workspaceNamespaces` enabled is below. Outcome = 1 x SA, 1 x Role, 1 x RoleBinding, all in the coder (`.Release.Namespace`) namespace PLUS a Role and RoleBinding in the `dev-ws` namespace with each of the RoleBindings referencing the coder SA in the coder (`.Release.Namespace`) namespace: ``` ➜ coder git:(feat/helm_namespace_rbac_improvements) ✗ helm template -n coder coder . --set coder.image.tag=v2.25.1 --set-json 'coder.serviceAccount.workspaceNamespaces=[{"name":"dev-ws","workspacePerms":true,"enableDeployments":true,"extraRules":[]}]' --- ... --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: coder-workspace-perms namespace: coder rules: - apiGroups: [""] resources: ["pods"] verbs: - create - delete - deletecollection - get - list - patch - update - watch - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: - create - delete - deletecollection - get - list - patch - update - watch - apiGroups: - apps resources: - deployments verbs: - create - delete - deletecollection - get - list - patch - update - watch --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: coder-workspace-perms namespace: dev-ws rules: - apiGroups: [""] resources: ["pods"] verbs: - create - delete - deletecollection - get - list - patch - update - watch - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: - create - delete - deletecollection - get - list - patch - update - watch - apiGroups: - apps resources: - deployments verbs: - create - delete - deletecollection - get - list - patch - update - watch --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: "coder" namespace: coder subjects: - kind: ServiceAccount name: "coder" roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: coder-workspace-perms --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: "coder" namespace: dev-ws subjects: - kind: ServiceAccount name: "coder" namespace: coder roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: coder-workspace-perms --- ```
243 lines
5.9 KiB
Smarty
243 lines
5.9 KiB
Smarty
{{/*
|
|
Expand the name of the chart.
|
|
*/}}
|
|
{{- define "coder.name" -}}
|
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Create chart name and version as used by the chart label.
|
|
*/}}
|
|
{{- define "coder.chart" -}}
|
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Selector labels
|
|
|
|
!!!!! DO NOT ADD ANY MORE SELECTORS. IT IS A BREAKING CHANGE !!!!!
|
|
*/}}
|
|
{{- define "coder.selectorLabels" -}}
|
|
app.kubernetes.io/name: {{ include "coder.name" . }}
|
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Common labels
|
|
*/}}
|
|
{{- define "coder.labels" -}}
|
|
helm.sh/chart: {{ include "coder.chart" . }}
|
|
{{ include "coder.selectorLabels" . }}
|
|
app.kubernetes.io/part-of: {{ include "coder.name" . }}
|
|
{{- if .Chart.AppVersion }}
|
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
|
{{- end }}
|
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder Docker image URI
|
|
*/}}
|
|
{{- define "coder.image" -}}
|
|
{{- if and (eq .Values.coder.image.tag "") (eq .Chart.AppVersion "0.1.0") -}}
|
|
{{ fail "You must specify the coder.image.tag value if you're installing the Helm chart directly from Git." }}
|
|
{{- end -}}
|
|
{{ .Values.coder.image.repo }}:{{ .Values.coder.image.tag | default (printf "v%v" .Chart.AppVersion) }}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder TLS enabled.
|
|
*/}}
|
|
{{- define "coder.tlsEnabled" -}}
|
|
{{- if hasKey .Values.coder "tls" -}}
|
|
{{- if .Values.coder.tls.secretNames -}}
|
|
true
|
|
{{- else -}}
|
|
false
|
|
{{- end -}}
|
|
{{- else -}}
|
|
false
|
|
{{- end -}}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder TLS environment variables.
|
|
*/}}
|
|
{{- define "coder.tlsEnv" }}
|
|
{{- if eq (include "coder.tlsEnabled" .) "true" }}
|
|
- name: CODER_TLS_ENABLE
|
|
value: "true"
|
|
- name: CODER_TLS_ADDRESS
|
|
value: "0.0.0.0:8443"
|
|
- name: CODER_TLS_CERT_FILE
|
|
value: "{{ range $idx, $secretName := .Values.coder.tls.secretNames -}}{{ if $idx }},{{ end }}/etc/ssl/certs/coder/{{ $secretName }}/tls.crt{{- end }}"
|
|
- name: CODER_TLS_KEY_FILE
|
|
value: "{{ range $idx, $secretName := .Values.coder.tls.secretNames -}}{{ if $idx }},{{ end }}/etc/ssl/certs/coder/{{ $secretName }}/tls.key{{- end }}"
|
|
{{- end }}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder default access URL
|
|
*/}}
|
|
{{- define "coder.defaultAccessURL" }}
|
|
{{- if eq (include "coder.tlsEnabled" .) "true" -}}
|
|
https
|
|
{{- else -}}
|
|
http
|
|
{{- end -}}
|
|
://coder.{{ .Release.Namespace }}.svc.cluster.local
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder volume definitions.
|
|
*/}}
|
|
{{- define "coder.volumeList" }}
|
|
{{- if hasKey .Values.coder "tls" -}}
|
|
{{- range $secretName := .Values.coder.tls.secretNames }}
|
|
- name: "tls-{{ $secretName }}"
|
|
secret:
|
|
secretName: {{ $secretName | quote }}
|
|
{{ end -}}
|
|
{{- end }}
|
|
{{ range $secret := .Values.coder.certs.secrets -}}
|
|
- name: "ca-cert-{{ $secret.name }}"
|
|
secret:
|
|
secretName: {{ $secret.name | quote }}
|
|
{{ end -}}
|
|
{{ if gt (len .Values.coder.volumes) 0 -}}
|
|
{{ toYaml .Values.coder.volumes }}
|
|
{{ end -}}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder volumes yaml.
|
|
*/}}
|
|
{{- define "coder.volumes" }}
|
|
{{- if trim (include "coder.volumeList" .) -}}
|
|
volumes:
|
|
{{- include "coder.volumeList" . -}}
|
|
{{- else -}}
|
|
volumes: []
|
|
{{- end -}}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder volume mounts.
|
|
*/}}
|
|
{{- define "coder.volumeMountList" }}
|
|
{{- if hasKey .Values.coder "tls" }}
|
|
{{ range $secretName := .Values.coder.tls.secretNames -}}
|
|
- name: "tls-{{ $secretName }}"
|
|
mountPath: "/etc/ssl/certs/coder/{{ $secretName }}"
|
|
readOnly: true
|
|
{{ end -}}
|
|
{{- end }}
|
|
{{ range $secret := .Values.coder.certs.secrets -}}
|
|
- name: "ca-cert-{{ $secret.name }}"
|
|
mountPath: "/etc/ssl/certs/{{ $secret.name }}.crt"
|
|
subPath: {{ $secret.key | quote }}
|
|
readOnly: true
|
|
{{ end -}}
|
|
{{ if gt (len .Values.coder.volumeMounts) 0 -}}
|
|
{{ toYaml .Values.coder.volumeMounts }}
|
|
{{ end -}}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder volume mounts yaml.
|
|
*/}}
|
|
{{- define "coder.volumeMounts" }}
|
|
{{- if trim (include "coder.volumeMountList" .) -}}
|
|
volumeMounts:
|
|
{{- include "coder.volumeMountList" . -}}
|
|
{{- else -}}
|
|
volumeMounts: []
|
|
{{- end -}}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Coder ingress wildcard hostname with the wildcard suffix stripped.
|
|
*/}}
|
|
{{- define "coder.ingressWildcardHost" -}}
|
|
{{/* This regex replace is required as the original input including the suffix
|
|
* is not a legal ingress host. We need to remove the suffix and keep the
|
|
* wildcard '*'.
|
|
*
|
|
* - '\\*' Starts with '*'
|
|
* - '[^.]*' Suffix is 0 or more characters, '-suffix'
|
|
* - '(' Start domain capture group
|
|
* - '\\.' The domain should be separated with a '.' from the subdomain
|
|
* - '.*' Rest of the domain.
|
|
* - ')' $1 is the ''.example.com'
|
|
*/}}
|
|
{{- regexReplaceAll "\\*[^.]*(\\..*)" .Values.coder.ingress.wildcardHost "*${1}" -}}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Fail on fully deprecated values or deprecated value combinations. This is
|
|
included at the top of coder.yaml.
|
|
*/}}
|
|
{{- define "coder.verifyDeprecated" }}
|
|
{{/*
|
|
Deprecated value coder.tls.secretName must not be used.
|
|
*/}}
|
|
{{- if .Values.coder.tls.secretName }}
|
|
{{ fail "coder.tls.secretName is deprecated, use coder.tls.secretNames instead." }}
|
|
{{- end }}
|
|
{{- end }}
|
|
|
|
{{/*
|
|
Renders a value that contains a template.
|
|
Usage:
|
|
{{ include "coder.renderTemplate" ( dict "value" .Values.path.to.the.Value "context" $) }}
|
|
*/}}
|
|
{{- define "coder.renderTemplate" -}}
|
|
{{- if typeIs "string" .value }}
|
|
{{- tpl .value .context }}
|
|
{{- else }}
|
|
{{- tpl (.value | toYaml) .context }}
|
|
{{- end }}
|
|
{{- end -}}
|
|
|
|
{{- define "libcoder.rbac.rules.basic" -}}
|
|
- apiGroups: [""]
|
|
resources: ["pods"]
|
|
verbs:
|
|
- create
|
|
- delete
|
|
- deletecollection
|
|
- get
|
|
- list
|
|
- patch
|
|
- update
|
|
- watch
|
|
- apiGroups: [""]
|
|
resources: ["persistentvolumeclaims"]
|
|
verbs:
|
|
- create
|
|
- delete
|
|
- deletecollection
|
|
- get
|
|
- list
|
|
- patch
|
|
- update
|
|
- watch
|
|
{{- end }}
|
|
|
|
{{- define "libcoder.rbac.rules.deployments" -}}
|
|
- apiGroups:
|
|
- apps
|
|
resources:
|
|
- deployments
|
|
verbs:
|
|
- create
|
|
- delete
|
|
- deletecollection
|
|
- get
|
|
- list
|
|
- patch
|
|
- update
|
|
- watch
|
|
{{- end }}
|
|
|