diff --git a/.prettierignore b/.prettierignore index 9296d15d8802e..d68357703d7ce 100644 --- a/.prettierignore +++ b/.prettierignore @@ -67,7 +67,7 @@ scaletest/terraform/secrets.tfvars # .prettierignore.include: # Helm templates contain variables that are invalid YAML and can't be formatted # by Prettier. -helm/templates/*.yaml +helm/**/templates/*.yaml # Terraform state files used in tests, these are automatically generated. # Example: provisioner/terraform/testdata/instance-id/instance-id.tfstate.json diff --git a/.prettierignore.include b/.prettierignore.include index 1f60eda9c54a7..975c00ca21b84 100644 --- a/.prettierignore.include +++ b/.prettierignore.include @@ -1,6 +1,6 @@ # Helm templates contain variables that are invalid YAML and can't be formatted # by Prettier. -helm/templates/*.yaml +helm/**/templates/*.yaml # Terraform state files used in tests, these are automatically generated. # Example: provisioner/terraform/testdata/instance-id/instance-id.tfstate.json diff --git a/Makefile b/Makefile index c9089a9d4e452..8bb681c9d4020 100644 --- a/Makefile +++ b/Makefile @@ -553,7 +553,7 @@ coderd/apidoc/swagger.json: $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS) ./scripts/apidocgen/generate.sh pnpm run format:write:only ./docs/api ./docs/manifest.json ./coderd/apidoc/swagger.json -update-golden-files: cli/testdata/.gen-golden helm/tests/testdata/.gen-golden scripts/ci-report/testdata/.gen-golden enterprise/cli/testdata/.gen-golden +update-golden-files: cli/testdata/.gen-golden helm/coder/tests/testdata/.gen-golden helm/provisioner/tests/testdata/.gen-golden scripts/ci-report/testdata/.gen-golden enterprise/cli/testdata/.gen-golden .PHONY: update-golden-files cli/testdata/.gen-golden: $(wildcard cli/testdata/*.golden) $(wildcard cli/*.tpl) $(GO_SRC_FILES) $(wildcard cli/*_test.go) @@ -564,8 +564,12 @@ enterprise/cli/testdata/.gen-golden: $(wildcard enterprise/cli/testdata/*.golden go test ./enterprise/cli -run="TestEnterpriseCommandHelp" -update touch "$@" -helm/tests/testdata/.gen-golden: $(wildcard helm/tests/testdata/*.yaml) $(wildcard helm/tests/testdata/*.golden) $(GO_SRC_FILES) $(wildcard helm/tests/*_test.go) - go test ./helm/tests -run=TestUpdateGoldenFiles -update +helm/coder/tests/testdata/.gen-golden: $(wildcard helm/coder/tests/testdata/*.yaml) $(wildcard helm/coder/tests/testdata/*.golden) $(GO_SRC_FILES) $(wildcard helm/coder/tests/*_test.go) + go test ./helm/coder/tests -run=TestUpdateGoldenFiles -update + touch "$@" + +helm/provisioner/tests/testdata/.gen-golden: $(wildcard helm/provisioner/tests/testdata/*.yaml) $(wildcard helm/provisioner/tests/testdata/*.golden) $(GO_SRC_FILES) $(wildcard helm/provisioner/tests/*_test.go) + go test ./helm/provisioner/tests -run=TestUpdateGoldenFiles -update touch "$@" scripts/ci-report/testdata/.gen-golden: $(wildcard scripts/ci-report/testdata/*) $(wildcard scripts/ci-report/*.go) diff --git a/docs/admin/configure.md b/docs/admin/configure.md index 25f6d87583763..2240ef4ed5d62 100644 --- a/docs/admin/configure.md +++ b/docs/admin/configure.md @@ -42,7 +42,7 @@ If you are providing TLS certificates directly to the Coder server, either 1. Use a single certificate and key for both the root and wildcard domains. 2. Configure multiple certificates and keys via - [`coder.tls.secretNames`](https://github.com/coder/coder/blob/main/helm/values.yaml) in the Helm Chart, or + [`coder.tls.secretNames`](https://github.com/coder/coder/blob/main/helm/coder/values.yaml) in the Helm Chart, or [`--tls-cert-file`](../cli/server.md#--tls-cert-file) and [`--tls-key-file`](../cli/server.md#--tls-key-file) command line options (these both take a comma separated list of files; list certificates and their respective keys in the same order). diff --git a/docs/admin/scale.md b/docs/admin/scale.md index 5b5e2369f54fd..998314061fd52 100644 --- a/docs/admin/scale.md +++ b/docs/admin/scale.md @@ -42,7 +42,7 @@ Users accessing workspaces via SSH will consume fewer resources, as SSH connecti Workspace builds are CPU-intensive, as it relies on Terraform. Various [Terraform providers](https://registry.terraform.io/browse/providers) have different resource requirements. When tested with our [kubernetes](https://github.com/coder/coder/tree/main/examples/templates/kubernetes) template, `coderd` will consume roughly 0.25 cores per concurrent workspace build. -For effective provisioning, our helm chart prefers to schedule [one coderd replica per-node](https://github.com/coder/coder/blob/main/helm/values.yaml#L188-L202). +For effective provisioning, our helm chart prefers to schedule [one coderd replica per-node](https://github.com/coder/coder/blob/main/helm/coder/values.yaml#L188-L202). We recommend: diff --git a/docs/install/kubernetes.md b/docs/install/kubernetes.md index ade4b058c2dcf..11e8138d7c6d6 100644 --- a/docs/install/kubernetes.md +++ b/docs/install/kubernetes.md @@ -105,7 +105,7 @@ to log in and manage templates. > You can view our > [Helm README](https://github.com/coder/coder/blob/main/helm#readme) for > details on the values that are available, or you can view the - > [values.yaml](https://github.com/coder/coder/blob/main/helm/values.yaml) + > [values.yaml](https://github.com/coder/coder/blob/main/helm/coder/values.yaml) > file directly. 1. Run the following command to install the chart in your cluster. diff --git a/helm/Makefile b/helm/Makefile index a3f689b1637af..4010cf42d64fb 100644 --- a/helm/Makefile +++ b/helm/Makefile @@ -13,6 +13,13 @@ all: lint lint: lint/helm .PHONY: lint -lint/helm: - helm lint --strict --set coder.image.tag=v0.0.1 . +lint/helm: lint/helm/coder lint/helm/provisioner .PHONY: lint/helm + +lint/helm/coder: + helm lint --strict --set coder.image.tag=v0.0.1 coder/ +.PHONY: lint/helm/coder + +lint/helm/provisioner: + helm lint --strict --set coder.image.tag=v0.0.1 provisioner/ +.PHONY: lint/helm/provisioner diff --git a/helm/.helmignore b/helm/coder/.helmignore similarity index 100% rename from helm/.helmignore rename to helm/coder/.helmignore diff --git a/helm/coder/Chart.lock b/helm/coder/Chart.lock new file mode 100644 index 0000000000000..9692722e192f1 --- /dev/null +++ b/helm/coder/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: libcoder + repository: file://../libcoder + version: 0.1.0 +digest: sha256:5c9a99109258073b590a9f98268490ef387fde24c0c7c7ade9c1a8c7ef5e6e10 +generated: "2023-08-08T07:27:19.677972411Z" diff --git a/helm/Chart.yaml b/helm/coder/Chart.yaml similarity index 85% rename from helm/Chart.yaml rename to helm/coder/Chart.yaml index a68aa330d8d49..99f6b710474c3 100644 --- a/helm/Chart.yaml +++ b/helm/coder/Chart.yaml @@ -21,9 +21,14 @@ keywords: - coder - terraform sources: - - https://github.com/coder/coder/tree/main/helm + - https://github.com/coder/coder/tree/main/helm/coder icon: https://helm.coder.com/coder_logo_black.png maintainers: - name: Coder Technologies, Inc. email: support@coder.com url: https://coder.com/contact + +dependencies: + - name: libcoder + version: 0.1.0 + repository: file://../libcoder diff --git a/helm/README.md b/helm/coder/README.md similarity index 100% rename from helm/README.md rename to helm/coder/README.md diff --git a/helm/coder/charts/libcoder-0.1.0.tgz b/helm/coder/charts/libcoder-0.1.0.tgz new file mode 100644 index 0000000000000..b799de7d00819 Binary files /dev/null and b/helm/coder/charts/libcoder-0.1.0.tgz differ diff --git a/helm/templates/NOTES.txt b/helm/coder/templates/NOTES.txt similarity index 100% rename from helm/templates/NOTES.txt rename to helm/coder/templates/NOTES.txt diff --git a/helm/coder/templates/_coder.tpl b/helm/coder/templates/_coder.tpl new file mode 100644 index 0000000000000..98a89ff5d419a --- /dev/null +++ b/helm/coder/templates/_coder.tpl @@ -0,0 +1,102 @@ +{{/* +Service account to merge into the libcoder template +*/}} +{{- define "coder.serviceaccount" -}} +{{- end -}} + +{{/* +Deployment to merge into the libcoder template +*/}} +{{- define "coder.deployment" -}} +spec: + template: + spec: + containers: + - +{{ include "libcoder.containerspec" (list . "coder.containerspec") | indent 8}} + +{{- end -}} + +{{/* +ContainerSpec for the Coder container of the Coder deployment +*/}} +{{- define "coder.containerspec" -}} +args: +{{- if .Values.coder.commandArgs }} + {{- toYaml .Values.coder.commandArgs | nindent 12 }} +{{- else }} + {{- if .Values.coder.workspaceProxy }} +- wsproxy + {{- end }} +- server +{{- end }} +env: +- name: CODER_HTTP_ADDRESS + value: "0.0.0.0:8080" +- name: CODER_PROMETHEUS_ADDRESS + value: "0.0.0.0:2112" +{{- if .Values.provisionerDaemon.pskSecretName }} +- name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + name: {{ .Values.provisionerDaemon.pskSecretName | quote }} + key: psk +{{- end }} + # Set the default access URL so a `helm apply` works by default. + # See: https://github.com/coder/coder/issues/5024 +{{- $hasAccessURL := false }} +{{- range .Values.coder.env }} +{{- if eq .name "CODER_ACCESS_URL" }} +{{- $hasAccessURL = true }} +{{- end }} +{{- end }} +{{- if not $hasAccessURL }} +- name: CODER_ACCESS_URL + value: {{ include "coder.defaultAccessURL" . | quote }} +{{- end }} +# Used for inter-pod communication with high-availability. +- name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP +- name: CODER_DERP_SERVER_RELAY_URL + value: "http://$(KUBE_POD_IP):8080" +{{- include "coder.tlsEnv" . }} +{{- with .Values.coder.env }} +{{ toYaml . }} +{{- end }} +ports: +- name: "http" + containerPort: 8080 + protocol: TCP + {{- if eq (include "coder.tlsEnabled" .) "true" }} +- name: "https" + containerPort: 8443 + protocol: TCP + {{- end }} + {{- range .Values.coder.env }} + {{- if eq .name "CODER_PROMETHEUS_ENABLE" }} + {{/* + This sadly has to be nested to avoid evaluating the second part + of the condition too early and potentially getting type errors if + the value is not a string (like a `valueFrom`). We do not support + `valueFrom` for this env var specifically. + */}} + {{- if eq .value "true" }} +- name: "prometheus-http" + containerPort: 2112 + protocol: TCP + {{- end }} + {{- end }} + {{- end }} +readinessProbe: + httpGet: + path: /healthz + port: "http" + scheme: "HTTP" +livenessProbe: + httpGet: + path: /healthz + port: "http" + scheme: "HTTP" +{{- end }} diff --git a/helm/coder/templates/coder.yaml b/helm/coder/templates/coder.yaml new file mode 100644 index 0000000000000..65eaac00ac001 --- /dev/null +++ b/helm/coder/templates/coder.yaml @@ -0,0 +1,5 @@ +--- +{{ include "libcoder.serviceaccount" (list . "coder.serviceaccount") }} + +--- +{{ include "libcoder.deployment" (list . "coder.deployment") }} diff --git a/helm/templates/extra-templates.yaml b/helm/coder/templates/extra-templates.yaml similarity index 100% rename from helm/templates/extra-templates.yaml rename to helm/coder/templates/extra-templates.yaml diff --git a/helm/templates/ingress.yaml b/helm/coder/templates/ingress.yaml similarity index 100% rename from helm/templates/ingress.yaml rename to helm/coder/templates/ingress.yaml diff --git a/helm/coder/templates/rbac.yaml b/helm/coder/templates/rbac.yaml new file mode 100644 index 0000000000000..07fb36d876824 --- /dev/null +++ b/helm/coder/templates/rbac.yaml @@ -0,0 +1 @@ +{{ include "libcoder.rbac.tpl" . }} diff --git a/helm/templates/service.yaml b/helm/coder/templates/service.yaml similarity index 100% rename from helm/templates/service.yaml rename to helm/coder/templates/service.yaml diff --git a/helm/tests/chart_test.go b/helm/coder/tests/chart_test.go similarity index 91% rename from helm/tests/chart_test.go rename to helm/coder/tests/chart_test.go index 7442be08fc2e3..451e4407f9abe 100644 --- a/helm/tests/chart_test.go +++ b/helm/coder/tests/chart_test.go @@ -20,10 +20,10 @@ import ( // All values and golden files are located in the `testdata` directory. // To update golden files, run `go test . -update`. -// UpdateGoldenFiles is a flag that can be set to update golden files. -var UpdateGoldenFiles = flag.Bool("update", false, "Update golden files") +// updateGoldenFiles is a flag that can be set to update golden files. +var updateGoldenFiles = flag.Bool("update", false, "Update golden files") -var TestCases = []TestCase{ +var testCases = []testCase{ { name: "default_values", expectedError: "", @@ -56,24 +56,28 @@ var TestCases = []TestCase{ name: "command_args", expectedError: "", }, + { + name: "provisionerd_psk", + expectedError: "", + }, } -type TestCase struct { +type testCase struct { name string // Name of the test case. This is used to control which values and golden file are used. expectedError string // Expected error from running `helm template`. } -func (tc TestCase) valuesFilePath() string { +func (tc testCase) valuesFilePath() string { return filepath.Join("./testdata", tc.name+".yaml") } -func (tc TestCase) goldenFilePath() string { +func (tc testCase) goldenFilePath() string { return filepath.Join("./testdata", tc.name+".golden") } func TestRenderChart(t *testing.T) { t.Parallel() - if *UpdateGoldenFiles { + if *updateGoldenFiles { t.Skip("Golden files are being updated. Skipping test.") } if testutil.InCI() { @@ -85,7 +89,7 @@ func TestRenderChart(t *testing.T) { // Ensure that Helm is available in $PATH helmPath := lookupHelm(t) - for _, tc := range TestCases { + for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() @@ -121,12 +125,12 @@ func TestRenderChart(t *testing.T) { func TestUpdateGoldenFiles(t *testing.T) { t.Parallel() - if !*UpdateGoldenFiles { + if !*updateGoldenFiles { t.Skip("Run with -update to update golden files") } helmPath := lookupHelm(t) - for _, tc := range TestCases { + for _, tc := range testCases { if tc.expectedError != "" { t.Logf("skipping test case %q with render error", tc.name) continue diff --git a/helm/tests/testdata/command.golden b/helm/coder/tests/testdata/command.golden similarity index 61% rename from helm/tests/testdata/command.golden rename to helm/coder/tests/testdata/command.golden index 616971e98d458..852ee36330ed2 100644 --- a/helm/tests/testdata/command.golden +++ b/helm/coder/tests/testdata/command.golden @@ -3,16 +3,15 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: "coder" - annotations: - {} + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -100,37 +99,32 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: coder + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder template: metadata: + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 spec: - serviceAccountName: "coder" - restartPolicy: Always - terminationGracePeriodSeconds: 60 affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -144,55 +138,52 @@ spec: topologyKey: kubernetes.io/hostname weight: 1 containers: - - name: coder - image: "ghcr.io/coder/coder:latest" - imagePullPolicy: IfNotPresent - command: - - /opt/colin - args: - - server - resources: - {} - lifecycle: - {} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - - name: CODER_ACCESS_URL - value: "http://coder.default.svc.cluster.local" - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: null - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - volumeMounts: [] + - args: + - server + command: + - /opt/colin + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_ACCESS_URL + value: http://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder + terminationGracePeriodSeconds: 60 volumes: [] diff --git a/helm/tests/testdata/command.yaml b/helm/coder/tests/testdata/command.yaml similarity index 100% rename from helm/tests/testdata/command.yaml rename to helm/coder/tests/testdata/command.yaml diff --git a/helm/tests/testdata/command_args.golden b/helm/coder/tests/testdata/command_args.golden similarity index 61% rename from helm/tests/testdata/command_args.golden rename to helm/coder/tests/testdata/command_args.golden index 92e87fd58097c..98bce5214c48e 100644 --- a/helm/tests/testdata/command_args.golden +++ b/helm/coder/tests/testdata/command_args.golden @@ -3,16 +3,15 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: "coder" - annotations: - {} + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -100,37 +99,32 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: coder + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder template: metadata: + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 spec: - serviceAccountName: "coder" - restartPolicy: Always - terminationGracePeriodSeconds: 60 affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -144,56 +138,53 @@ spec: topologyKey: kubernetes.io/hostname weight: 1 containers: - - name: coder - image: "ghcr.io/coder/coder:latest" - imagePullPolicy: IfNotPresent - command: - - /opt/coder - args: - - arg1 - - arg2 - resources: - {} - lifecycle: - {} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - - name: CODER_ACCESS_URL - value: "http://coder.default.svc.cluster.local" - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: null - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - volumeMounts: [] + - args: + - arg1 + - arg2 + command: + - /opt/coder + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_ACCESS_URL + value: http://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder + terminationGracePeriodSeconds: 60 volumes: [] diff --git a/helm/tests/testdata/command_args.yaml b/helm/coder/tests/testdata/command_args.yaml similarity index 100% rename from helm/tests/testdata/command_args.yaml rename to helm/coder/tests/testdata/command_args.yaml diff --git a/helm/tests/testdata/default_values.golden b/helm/coder/tests/testdata/default_values.golden similarity index 61% rename from helm/tests/testdata/default_values.golden rename to helm/coder/tests/testdata/default_values.golden index cb1988e1ab3e9..36d9fa171b63e 100644 --- a/helm/tests/testdata/default_values.golden +++ b/helm/coder/tests/testdata/default_values.golden @@ -3,16 +3,15 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: "coder" - annotations: - {} + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -100,37 +99,32 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: coder + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder template: metadata: + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 spec: - serviceAccountName: "coder" - restartPolicy: Always - terminationGracePeriodSeconds: 60 affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -144,55 +138,52 @@ spec: topologyKey: kubernetes.io/hostname weight: 1 containers: - - name: coder - image: "ghcr.io/coder/coder:latest" - imagePullPolicy: IfNotPresent - command: - - /opt/coder - args: - - server - resources: - {} - lifecycle: - {} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - - name: CODER_ACCESS_URL - value: "http://coder.default.svc.cluster.local" - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: null - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - volumeMounts: [] + - args: + - server + command: + - /opt/coder + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_ACCESS_URL + value: http://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder + terminationGracePeriodSeconds: 60 volumes: [] diff --git a/helm/tests/testdata/default_values.yaml b/helm/coder/tests/testdata/default_values.yaml similarity index 100% rename from helm/tests/testdata/default_values.yaml rename to helm/coder/tests/testdata/default_values.yaml diff --git a/helm/tests/testdata/labels_annotations.golden b/helm/coder/tests/testdata/labels_annotations.golden similarity index 64% rename from helm/tests/testdata/labels_annotations.golden rename to helm/coder/tests/testdata/labels_annotations.golden index e6f85d0dfa476..b0edb4346f191 100644 --- a/helm/tests/testdata/labels_annotations.golden +++ b/helm/coder/tests/testdata/labels_annotations.golden @@ -3,16 +3,15 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: "coder" - annotations: - {} + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -100,43 +99,40 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: coder + annotations: + com.coder/annotation/baz: qux + com.coder/annotation/foo: bar labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 com.coder/label/baz: qux com.coder/label/foo: bar - annotations: - com.coder/annotation/baz: qux - com.coder/annotation/foo: bar + helm.sh/chart: coder-0.1.0 + name: coder spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder template: metadata: + annotations: + com.coder/podAnnotation/baz: qux + com.coder/podAnnotation/foo: bar labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 com.coder/podLabel/baz: qux com.coder/podLabel/foo: bar - annotations: - com.coder/podAnnotation/baz: qux - com.coder/podAnnotation/foo: bar + helm.sh/chart: coder-0.1.0 spec: - serviceAccountName: "coder" - restartPolicy: Always - terminationGracePeriodSeconds: 60 affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -150,55 +146,52 @@ spec: topologyKey: kubernetes.io/hostname weight: 1 containers: - - name: coder - image: "ghcr.io/coder/coder:latest" - imagePullPolicy: IfNotPresent - command: - - /opt/coder - args: - - server - resources: - {} - lifecycle: - {} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - - name: CODER_ACCESS_URL - value: "http://coder.default.svc.cluster.local" - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: null - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - volumeMounts: [] + - args: + - server + command: + - /opt/coder + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_ACCESS_URL + value: http://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder + terminationGracePeriodSeconds: 60 volumes: [] diff --git a/helm/tests/testdata/labels_annotations.yaml b/helm/coder/tests/testdata/labels_annotations.yaml similarity index 100% rename from helm/tests/testdata/labels_annotations.yaml rename to helm/coder/tests/testdata/labels_annotations.yaml diff --git a/helm/tests/testdata/missing_values.yaml b/helm/coder/tests/testdata/missing_values.yaml similarity index 100% rename from helm/tests/testdata/missing_values.yaml rename to helm/coder/tests/testdata/missing_values.yaml diff --git a/helm/coder/tests/testdata/provisionerd_psk.golden b/helm/coder/tests/testdata/provisionerd_psk.golden new file mode 100644 index 0000000000000..f8cfe550eefff --- /dev/null +++ b/helm/coder/tests/testdata/provisionerd_psk.golden @@ -0,0 +1,194 @@ +--- +# Source: coder/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder +--- +# Source: coder/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-workspace-perms +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" +subjects: + - kind: ServiceAccount + name: "coder" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-workspace-perms +--- +# Source: coder/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: coder + labels: + helm.sh/chart: coder-0.1.0 + app.kubernetes.io/name: coder + app.kubernetes.io/instance: release-name + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: "0.1.0" + app.kubernetes.io/managed-by: Helm + annotations: + {} +spec: + type: LoadBalancer + sessionAffinity: ClientIP + ports: + - name: "http" + port: 80 + targetPort: "http" + protocol: TCP + externalTrafficPolicy: "Cluster" + selector: + app.kubernetes.io/name: coder + app.kubernetes.io/instance: release-name +--- +# Source: coder/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - coder + topologyKey: kubernetes.io/hostname + weight: 1 + containers: + - args: + - server + command: + - /opt/coder + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: coder-provisionerd-psk + - name: CODER_ACCESS_URL + value: http://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/coder/tests/testdata/provisionerd_psk.yaml b/helm/coder/tests/testdata/provisionerd_psk.yaml new file mode 100644 index 0000000000000..915b7aeb66f0f --- /dev/null +++ b/helm/coder/tests/testdata/provisionerd_psk.yaml @@ -0,0 +1,5 @@ +coder: + image: + tag: latest +provisionerDaemon: + pskSecretName: "coder-provisionerd-psk" diff --git a/helm/tests/testdata/sa.golden b/helm/coder/tests/testdata/sa.golden similarity index 60% rename from helm/tests/testdata/sa.golden rename to helm/coder/tests/testdata/sa.golden index 5e94a67818c62..940b761dd3f79 100644 --- a/helm/tests/testdata/sa.golden +++ b/helm/coder/tests/testdata/sa.golden @@ -3,22 +3,22 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: "coder-service-account" - annotations: + annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/coder-service-account labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder-service-account --- # Source: coder/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: coder-workspace-perms + name: coder-service-account-workspace-perms rules: - apiGroups: [""] resources: ["pods"] @@ -67,7 +67,7 @@ subjects: roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: coder-workspace-perms + name: coder-service-account-workspace-perms --- # Source: coder/templates/service.yaml apiVersion: v1 @@ -100,37 +100,32 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: coder + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder template: metadata: + annotations: {} labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" app.kubernetes.io/managed-by: Helm - annotations: - {} + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 spec: - serviceAccountName: "coder-service-account" - restartPolicy: Always - terminationGracePeriodSeconds: 60 affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -144,55 +139,52 @@ spec: topologyKey: kubernetes.io/hostname weight: 1 containers: - - name: coder - image: "ghcr.io/coder/coder:latest" - imagePullPolicy: IfNotPresent - command: - - /opt/coder - args: - - server - resources: - {} - lifecycle: - {} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - - name: CODER_ACCESS_URL - value: "http://coder.default.svc.cluster.local" - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: null - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - volumeMounts: [] + - args: + - server + command: + - /opt/coder + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_ACCESS_URL + value: http://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder-service-account + terminationGracePeriodSeconds: 60 volumes: [] diff --git a/helm/tests/testdata/sa.yaml b/helm/coder/tests/testdata/sa.yaml similarity index 100% rename from helm/tests/testdata/sa.yaml rename to helm/coder/tests/testdata/sa.yaml diff --git a/helm/coder/tests/testdata/tls.golden b/helm/coder/tests/testdata/tls.golden new file mode 100644 index 0000000000000..75f0794a7945d --- /dev/null +++ b/helm/coder/tests/testdata/tls.golden @@ -0,0 +1,210 @@ +--- +# Source: coder/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder +--- +# Source: coder/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-workspace-perms +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" +subjects: + - kind: ServiceAccount + name: "coder" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-workspace-perms +--- +# Source: coder/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: coder + labels: + helm.sh/chart: coder-0.1.0 + app.kubernetes.io/name: coder + app.kubernetes.io/instance: release-name + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: "0.1.0" + app.kubernetes.io/managed-by: Helm + annotations: + {} +spec: + type: LoadBalancer + sessionAffinity: ClientIP + ports: + - name: "http" + port: 80 + targetPort: "http" + protocol: TCP + - name: "https" + port: 443 + targetPort: "https" + protocol: TCP + externalTrafficPolicy: "Cluster" + selector: + app.kubernetes.io/name: coder + app.kubernetes.io/instance: release-name +--- +# Source: coder/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - coder + topologyKey: kubernetes.io/hostname + weight: 1 + containers: + - args: + - server + command: + - /opt/coder + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_ACCESS_URL + value: https://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + - name: CODER_TLS_ENABLE + value: "true" + - name: CODER_TLS_ADDRESS + value: 0.0.0.0:8443 + - name: CODER_TLS_CERT_FILE + value: /etc/ssl/certs/coder/coder-tls/tls.crt + - name: CODER_TLS_KEY_FILE + value: /etc/ssl/certs/coder/coder-tls/tls.key + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + - containerPort: 8443 + name: https + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /etc/ssl/certs/coder/coder-tls + name: tls-coder-tls + readOnly: true + restartPolicy: Always + serviceAccountName: coder + terminationGracePeriodSeconds: 60 + volumes: + - name: tls-coder-tls + secret: + secretName: coder-tls diff --git a/helm/tests/testdata/tls.yaml b/helm/coder/tests/testdata/tls.yaml similarity index 100% rename from helm/tests/testdata/tls.yaml rename to helm/coder/tests/testdata/tls.yaml diff --git a/helm/coder/tests/testdata/workspace_proxy.golden b/helm/coder/tests/testdata/workspace_proxy.golden new file mode 100644 index 0000000000000..6d03e49ff794e --- /dev/null +++ b/helm/coder/tests/testdata/workspace_proxy.golden @@ -0,0 +1,197 @@ +--- +# Source: coder/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder +--- +# Source: coder/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-workspace-perms +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" +subjects: + - kind: ServiceAccount + name: "coder" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-workspace-perms +--- +# Source: coder/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: coder + labels: + helm.sh/chart: coder-0.1.0 + app.kubernetes.io/name: coder + app.kubernetes.io/instance: release-name + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: "0.1.0" + app.kubernetes.io/managed-by: Helm + annotations: + {} +spec: + type: LoadBalancer + sessionAffinity: ClientIP + ports: + - name: "http" + port: 80 + targetPort: "http" + protocol: TCP + externalTrafficPolicy: "Cluster" + selector: + app.kubernetes.io/name: coder + app.kubernetes.io/instance: release-name +--- +# Source: coder/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + name: coder +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder + app.kubernetes.io/part-of: coder + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-0.1.0 + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - coder + topologyKey: kubernetes.io/hostname + weight: 1 + containers: + - args: + - wsproxy + - server + command: + - /opt/coder + env: + - name: CODER_HTTP_ADDRESS + value: 0.0.0.0:8080 + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_ACCESS_URL + value: http://coder.default.svc.cluster.local + - name: KUBE_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CODER_DERP_SERVER_RELAY_URL + value: http://$(KUBE_POD_IP):8080 + - name: CODER_PRIMARY_ACCESS_URL + value: https://dev.coder.com + - name: CODER_PROXY_SESSION_TOKEN + valueFrom: + secretKeyRef: + key: token + name: coder-workspace-proxy-session-token + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + name: coder + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/tests/testdata/workspace_proxy.yaml b/helm/coder/tests/testdata/workspace_proxy.yaml similarity index 100% rename from helm/tests/testdata/workspace_proxy.yaml rename to helm/coder/tests/testdata/workspace_proxy.yaml diff --git a/helm/values.yaml b/helm/coder/values.yaml similarity index 96% rename from helm/values.yaml rename to helm/coder/values.yaml index 43d317507d609..f6b43e4ee4dd0 100644 --- a/helm/values.yaml +++ b/helm/coder/values.yaml @@ -280,6 +280,16 @@ coder: # coder.commandArgs -- Set arguments for the entrypoint command of the Coder pod. commandArgs: [] +# provisionerDaemon -- Configuration for external provisioner daemons. +# +# This is an Enterprise feature. Contact sales@coder.com. +provisionerDaemon: + # provisionerDaemon.pskSecretName -- The name of the Kubernetes secret that contains the + # Pre-Shared Key (PSK) to use to authenticate external provisioner daemons with Coder. The + # secret must be in the same namespace as the Helm deployment, and contain an item called "psk" + # which contains the pre-shared key. + pskSecretName: "" + # extraTemplates -- Array of extra objects to deploy with the release. Strings # are evaluated as a template and can use template expansions and functions. All # other objects are used as yaml. diff --git a/helm/libcoder/Chart.yaml b/helm/libcoder/Chart.yaml new file mode 100644 index 0000000000000..90c881af5d62d --- /dev/null +++ b/helm/libcoder/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: libcoder +description: Coder library chart +home: https://github.com/coder/coder + +type: library +version: "0.1.0" +appVersion: "0.1.0" + +maintainers: + - name: Coder Technologies, Inc. + email: support@coder.com + url: https://coder.com/contact diff --git a/helm/libcoder/templates/_coder.yaml b/helm/libcoder/templates/_coder.yaml new file mode 100644 index 0000000000000..77cdbb2a3dfe5 --- /dev/null +++ b/helm/libcoder/templates/_coder.yaml @@ -0,0 +1,85 @@ +{{- define "libcoder.deployment.tpl" -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "coder.name" .}} + labels: + {{- include "coder.labels" . | nindent 4 }} + {{- with .Values.coder.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: {{ toYaml .Values.coder.annotations | nindent 4}} +spec: + replicas: {{ .Values.coder.replicaCount }} + selector: + matchLabels: + {{- include "coder.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "coder.labels" . | nindent 8 }} + {{- with .Values.coder.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- toYaml .Values.coder.podAnnotations | nindent 8 }} + spec: + serviceAccountName: {{ .Values.coder.serviceAccount.name | quote }} + restartPolicy: Always + {{- with .Values.coder.image.pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 60 + {{- with .Values.coder.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.coder.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.coder.nodeSelector }} + nodeSelector: + {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.coder.initContainers }} + initContainers: + {{ toYaml . | nindent 8 }} + {{- end }} + containers: [] + {{- include "coder.volumes" . | nindent 6 }} +{{- end -}} +{{- define "libcoder.deployment" -}} +{{- include "libcoder.util.merge" (append . "libcoder.deployment.tpl") -}} +{{- end -}} + +{{- define "libcoder.containerspec.tpl" -}} +name: coder +image: {{ include "coder.image" . | quote }} +imagePullPolicy: {{ .Values.coder.image.pullPolicy }} +command: + {{- toYaml .Values.coder.command | nindent 2 }} +resources: + {{- toYaml .Values.coder.resources | nindent 2 }} +lifecycle: + {{- toYaml .Values.coder.lifecycle | nindent 2 }} +securityContext: {{ toYaml .Values.coder.securityContext | nindent 2 }} +{{ include "coder.volumeMounts" . }} +{{- end -}} +{{- define "libcoder.containerspec" -}} +{{- include "libcoder.util.merge" (append . "libcoder.containerspec.tpl") -}} +{{- end -}} + +{{- define "libcoder.serviceaccount.tpl" -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.coder.serviceAccount.name | quote }} + annotations: {{ toYaml .Values.coder.serviceAccount.annotations | nindent 4 }} + labels: + {{- include "coder.labels" . | nindent 4 }} +{{- end -}} +{{- define "libcoder.serviceaccount" -}} +{{- include "libcoder.util.merge" (append . "libcoder.serviceaccount.tpl") -}} +{{- end -}} diff --git a/helm/templates/_helpers.tpl b/helm/libcoder/templates/_helpers.tpl similarity index 93% rename from helm/templates/_helpers.tpl rename to helm/libcoder/templates/_helpers.tpl index d884b28402000..9a6c5dfcfb82d 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/libcoder/templates/_helpers.tpl @@ -49,11 +49,15 @@ Coder Docker image URI Coder TLS enabled. */}} {{- define "coder.tlsEnabled" -}} -{{- if .Values.coder.tls.secretNames -}} -true -{{- else -}} -false -{{- end -}} + {{- if hasKey .Values.coder "tls" -}} + {{- if .Values.coder.tls.secretNames -}} + true + {{- else -}} + false + {{- end -}} + {{- else -}} + false + {{- end -}} {{- end }} {{/* @@ -88,11 +92,13 @@ http Coder volume definitions. */}} {{- define "coder.volumeList" }} -{{ range $secretName := .Values.coder.tls.secretNames -}} +{{- 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: @@ -119,11 +125,13 @@ volumes: [] 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" diff --git a/helm/templates/rbac.yaml b/helm/libcoder/templates/_rbac.yaml similarity index 85% rename from helm/templates/rbac.yaml rename to helm/libcoder/templates/_rbac.yaml index 3105e1a604b63..c60357ad2a796 100644 --- a/helm/templates/rbac.yaml +++ b/helm/libcoder/templates/_rbac.yaml @@ -1,9 +1,10 @@ +{{- define "libcoder.rbac.tpl" -}} {{- if .Values.coder.serviceAccount.workspacePerms }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: coder-workspace-perms + name: {{ .Values.coder.serviceAccount.name }}-workspace-perms rules: - apiGroups: [""] resources: ["pods"] @@ -53,5 +54,6 @@ subjects: roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: coder-workspace-perms + name: {{ .Values.coder.serviceAccount.name }}-workspace-perms {{- end }} +{{- end -}} diff --git a/helm/libcoder/templates/_util.yaml b/helm/libcoder/templates/_util.yaml new file mode 100644 index 0000000000000..ebdc13e3631ec --- /dev/null +++ b/helm/libcoder/templates/_util.yaml @@ -0,0 +1,13 @@ +{{- /* + libcoder.util.merge will merge two YAML templates and output the result. + This takes an array of three values: + - the top context + - the template name of the overrides (destination) + - the template name of the base (source) +*/}} +{{- define "libcoder.util.merge" -}} +{{- $top := first . -}} +{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}} +{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}} +{{- toYaml (merge $overrides $tpl) -}} +{{- end -}} diff --git a/helm/provisioner/Chart.lock b/helm/provisioner/Chart.lock new file mode 100644 index 0000000000000..b51a533086d42 --- /dev/null +++ b/helm/provisioner/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: libcoder + repository: file://../libcoder + version: 0.1.0 +digest: sha256:5c9a99109258073b590a9f98268490ef387fde24c0c7c7ade9c1a8c7ef5e6e10 +generated: "2023-08-07T12:43:45.49343898Z" diff --git a/helm/provisioner/Chart.yaml b/helm/provisioner/Chart.yaml new file mode 100644 index 0000000000000..e27e85ec12bd4 --- /dev/null +++ b/helm/provisioner/Chart.yaml @@ -0,0 +1,34 @@ +apiVersion: v2 +name: coder-provisioner +description: "External provisioner daemon for Coder. This is an Enterprise feature; contact sales@coder.com." +home: https://github.com/coder/coder + +# version and appVersion are injected at release and will always be shown as +# 0.1.0 in the repository. +# +# If you're installing the Helm chart directly from git it will have this +# version, which means the auto-generated image URI will be invalid. You can set +# "coder.image.tag" to the desired tag manually. +type: application +version: "0.1.0" +appVersion: "0.1.0" + +# Coder has a hard requirement on Kubernetes 1.19, as this version introduced +# the networking.k8s.io/v1 API. +kubeVersion: ">= 1.19.0-0" + +keywords: + - coder + - terraform +sources: + - https://github.com/coder/coder/tree/main/helm/provisioner +icon: https://helm.coder.com/coder_logo_black.png +maintainers: + - name: Coder Technologies, Inc. + email: support@coder.com + url: https://coder.com/contact + +dependencies: + - name: libcoder + version: 0.1.0 + repository: file://../libcoder diff --git a/helm/provisioner/charts/libcoder-0.1.0.tgz b/helm/provisioner/charts/libcoder-0.1.0.tgz new file mode 100644 index 0000000000000..638d50f976a7e Binary files /dev/null and b/helm/provisioner/charts/libcoder-0.1.0.tgz differ diff --git a/helm/provisioner/templates/_coder.tpl b/helm/provisioner/templates/_coder.tpl new file mode 100644 index 0000000000000..856f18bd33d6e --- /dev/null +++ b/helm/provisioner/templates/_coder.tpl @@ -0,0 +1,85 @@ +{{/* +Service account to merge into the libcoder template +*/}} +{{- define "coder.serviceaccount" -}} +{{- end }} + +{{/* +Deployment to merge into the libcoder template +*/}} +{{- define "coder.deployment" -}} +spec: + template: + spec: + containers: + - +{{ include "libcoder.containerspec" (list . "coder.containerspec") | indent 8}} + +{{- end }} + +{{/* +ContainerSpec for the Coder container of the Coder deployment +*/}} +{{- define "coder.containerspec" -}} +args: +{{- if .Values.coder.commandArgs }} + {{- toYaml .Values.coder.commandArgs | nindent 12 }} +{{- else }} +- provisionerd +- start +{{- end }} +env: +- name: CODER_PROMETHEUS_ADDRESS + value: "0.0.0.0:2112" +- name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + name: {{ .Values.provisionerDaemon.pskSecretName | quote }} + key: psk +{{- if include "provisioner.tags" . }} +- name: CODER_PROVISIONERD_TAGS + value: {{ include "provisioner.tags" . }} +{{- end }} + # Set the default access URL so a `helm apply` works by default. + # See: https://github.com/coder/coder/issues/5024 +{{- $hasAccessURL := false }} +{{- range .Values.coder.env }} +{{- if eq .name "CODER_URL" }} +{{- $hasAccessURL = true }} +{{- end }} +{{- end }} +{{- if not $hasAccessURL }} +- name: CODER_URL + value: {{ include "coder.defaultAccessURL" . | quote }} +{{- end }} +{{- with .Values.coder.env }} +{{ toYaml . }} +{{- end }} +ports: + {{- range .Values.coder.env }} + {{- if eq .name "CODER_PROMETHEUS_ENABLE" }} + {{/* + This sadly has to be nested to avoid evaluating the second part + of the condition too early and potentially getting type errors if + the value is not a string (like a `valueFrom`). We do not support + `valueFrom` for this env var specifically. + */}} + {{- if eq .value "true" }} +- name: "prometheus-http" + containerPort: 2112 + protocol: TCP + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{/* +Convert provisioner tags to the environment variable format +*/}} +{{- define "provisioner.tags" -}} + {{- $keys := keys .Values.provisionerDaemon.tags | sortAlpha -}} + {{- range $i, $key := $keys -}} + {{- $val := get $.Values.provisionerDaemon.tags $key -}} + {{- if ne $i 0 -}},{{- end -}}{{ $key }}={{ $val }} + {{- end -}} +{{- end -}} diff --git a/helm/provisioner/templates/coder.yaml b/helm/provisioner/templates/coder.yaml new file mode 100644 index 0000000000000..65eaac00ac001 --- /dev/null +++ b/helm/provisioner/templates/coder.yaml @@ -0,0 +1,5 @@ +--- +{{ include "libcoder.serviceaccount" (list . "coder.serviceaccount") }} + +--- +{{ include "libcoder.deployment" (list . "coder.deployment") }} diff --git a/helm/provisioner/templates/rbac.yaml b/helm/provisioner/templates/rbac.yaml new file mode 100644 index 0000000000000..07fb36d876824 --- /dev/null +++ b/helm/provisioner/templates/rbac.yaml @@ -0,0 +1 @@ +{{ include "libcoder.rbac.tpl" . }} diff --git a/helm/provisioner/tests/chart_test.go b/helm/provisioner/tests/chart_test.go new file mode 100644 index 0000000000000..95d516b3b04bf --- /dev/null +++ b/helm/provisioner/tests/chart_test.go @@ -0,0 +1,172 @@ +package tests // nolint: testpackage + +import ( + "bytes" + "flag" + "os" + "os/exec" + "path/filepath" + "runtime" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/xerrors" + + "github.com/coder/coder/testutil" +) + +// These tests run `helm template` with the values file specified in each test +// and compare the output to the contents of the corresponding golden file. +// All values and golden files are located in the `testdata` directory. +// To update golden files, run `go test . -update`. + +// updateGoldenFiles is a flag that can be set to update golden files. +var updateGoldenFiles = flag.Bool("update", false, "Update golden files") + +var testCases = []testCase{ + { + name: "default_values", + expectedError: "", + }, + { + name: "missing_values", + expectedError: `You must specify the coder.image.tag value if you're installing the Helm chart directly from Git.`, + }, + { + name: "sa", + expectedError: "", + }, + { + name: "labels_annotations", + expectedError: "", + }, + { + name: "command", + expectedError: "", + }, + { + name: "command_args", + expectedError: "", + }, + { + name: "provisionerd_psk", + expectedError: "", + }, +} + +type testCase struct { + name string // Name of the test case. This is used to control which values and golden file are used. + expectedError string // Expected error from running `helm template`. +} + +func (tc testCase) valuesFilePath() string { + return filepath.Join("./testdata", tc.name+".yaml") +} + +func (tc testCase) goldenFilePath() string { + return filepath.Join("./testdata", tc.name+".golden") +} + +func TestRenderChart(t *testing.T) { + t.Parallel() + if *updateGoldenFiles { + t.Skip("Golden files are being updated. Skipping test.") + } + if testutil.InCI() { + switch runtime.GOOS { + case "windows", "darwin": + t.Skip("Skipping tests on Windows and macOS in CI") + } + } + + // Ensure that Helm is available in $PATH + helmPath := lookupHelm(t) + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + // Ensure that the values file exists. + valuesFilePath := tc.valuesFilePath() + if _, err := os.Stat(valuesFilePath); os.IsNotExist(err) { + t.Fatalf("values file %q does not exist", valuesFilePath) + } + + // Run helm template with the values file. + templateOutput, err := runHelmTemplate(t, helmPath, "..", valuesFilePath) + if tc.expectedError != "" { + require.Error(t, err, "helm template should have failed") + require.Contains(t, templateOutput, tc.expectedError, "helm template output should contain expected error") + } else { + require.NoError(t, err, "helm template should not have failed") + require.NotEmpty(t, templateOutput, "helm template output should not be empty") + goldenFilePath := tc.goldenFilePath() + goldenBytes, err := os.ReadFile(goldenFilePath) + require.NoError(t, err, "failed to read golden file %q", goldenFilePath) + + // Remove carriage returns to make tests pass on Windows. + goldenBytes = bytes.Replace(goldenBytes, []byte("\r"), []byte(""), -1) + expected := string(goldenBytes) + + require.NoError(t, err, "failed to load golden file %q") + require.Equal(t, expected, templateOutput) + } + }) + } +} + +func TestUpdateGoldenFiles(t *testing.T) { + t.Parallel() + if !*updateGoldenFiles { + t.Skip("Run with -update to update golden files") + } + + helmPath := lookupHelm(t) + for _, tc := range testCases { + if tc.expectedError != "" { + t.Logf("skipping test case %q with render error", tc.name) + continue + } + + valuesPath := tc.valuesFilePath() + templateOutput, err := runHelmTemplate(t, helmPath, "..", valuesPath) + + require.NoError(t, err, "failed to run `helm template -f %q`", valuesPath) + + goldenFilePath := tc.goldenFilePath() + err = os.WriteFile(goldenFilePath, []byte(templateOutput), 0o644) // nolint:gosec + require.NoError(t, err, "failed to write golden file %q", goldenFilePath) + } + t.Log("Golden files updated. Please review the changes and commit them.") +} + +// runHelmTemplate runs helm template on the given chart with the given values and +// returns the raw output. +func runHelmTemplate(t testing.TB, helmPath, chartDir, valuesFilePath string) (string, error) { + // Ensure that valuesFilePath exists + if _, err := os.Stat(valuesFilePath); err != nil { + return "", xerrors.Errorf("values file %q does not exist: %w", valuesFilePath, err) + } + + cmd := exec.Command(helmPath, "template", chartDir, "-f", valuesFilePath, "--namespace", "default") + t.Logf("exec command: %v", cmd.Args) + out, err := cmd.CombinedOutput() + return string(out), err +} + +// lookupHelm ensures that Helm is available in $PATH and returns the path to the +// Helm executable. +func lookupHelm(t testing.TB) string { + helmPath, err := exec.LookPath("helm") + if err != nil { + t.Fatalf("helm not found in $PATH: %v", err) + return "" + } + t.Logf("Using helm at %q", helmPath) + return helmPath +} + +func TestMain(m *testing.M) { + flag.Parse() + os.Exit(m.Run()) +} diff --git a/helm/provisioner/tests/testdata/command.golden b/helm/provisioner/tests/testdata/command.golden new file mode 100644 index 0000000000000..e7ca572bf4575 --- /dev/null +++ b/helm/provisioner/tests/testdata/command.golden @@ -0,0 +1,135 @@ +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +--- +# Source: coder-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-provisioner-workspace-perms +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-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "coder-provisioner" +subjects: + - kind: ServiceAccount + name: "coder-provisioner" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-provisioner-workspace-perms +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder-provisioner + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + spec: + containers: + - args: + - provisionerd + - start + command: + - /opt/colin + env: + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: coder-provisioner-psk + - name: CODER_URL + value: http://coder.default.svc.cluster.local + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + name: coder + ports: null + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder-provisioner + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/provisioner/tests/testdata/command.yaml b/helm/provisioner/tests/testdata/command.yaml new file mode 100644 index 0000000000000..ef4c8de967f1a --- /dev/null +++ b/helm/provisioner/tests/testdata/command.yaml @@ -0,0 +1,5 @@ +coder: + image: + tag: latest + command: + - /opt/colin diff --git a/helm/provisioner/tests/testdata/command_args.golden b/helm/provisioner/tests/testdata/command_args.golden new file mode 100644 index 0000000000000..85f25e16f5869 --- /dev/null +++ b/helm/provisioner/tests/testdata/command_args.golden @@ -0,0 +1,135 @@ +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +--- +# Source: coder-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-provisioner-workspace-perms +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-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "coder-provisioner" +subjects: + - kind: ServiceAccount + name: "coder-provisioner" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-provisioner-workspace-perms +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder-provisioner + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + spec: + containers: + - args: + - arg1 + - arg2 + command: + - /opt/coder + env: + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: coder-provisioner-psk + - name: CODER_URL + value: http://coder.default.svc.cluster.local + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + name: coder + ports: null + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder-provisioner + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/provisioner/tests/testdata/command_args.yaml b/helm/provisioner/tests/testdata/command_args.yaml new file mode 100644 index 0000000000000..59d012aabbefb --- /dev/null +++ b/helm/provisioner/tests/testdata/command_args.yaml @@ -0,0 +1,6 @@ +coder: + image: + tag: latest + commandArgs: + - arg1 + - arg2 diff --git a/helm/provisioner/tests/testdata/default_values.golden b/helm/provisioner/tests/testdata/default_values.golden new file mode 100644 index 0000000000000..003d89626ba60 --- /dev/null +++ b/helm/provisioner/tests/testdata/default_values.golden @@ -0,0 +1,135 @@ +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +--- +# Source: coder-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-provisioner-workspace-perms +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-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "coder-provisioner" +subjects: + - kind: ServiceAccount + name: "coder-provisioner" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-provisioner-workspace-perms +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder-provisioner + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + spec: + containers: + - args: + - provisionerd + - start + command: + - /opt/coder + env: + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: coder-provisioner-psk + - name: CODER_URL + value: http://coder.default.svc.cluster.local + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + name: coder + ports: null + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder-provisioner + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/provisioner/tests/testdata/default_values.yaml b/helm/provisioner/tests/testdata/default_values.yaml new file mode 100644 index 0000000000000..70cdc8b472215 --- /dev/null +++ b/helm/provisioner/tests/testdata/default_values.yaml @@ -0,0 +1,3 @@ +coder: + image: + tag: latest diff --git a/helm/provisioner/tests/testdata/labels_annotations.golden b/helm/provisioner/tests/testdata/labels_annotations.golden new file mode 100644 index 0000000000000..85fa5fa1f1566 --- /dev/null +++ b/helm/provisioner/tests/testdata/labels_annotations.golden @@ -0,0 +1,143 @@ +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +--- +# Source: coder-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-provisioner-workspace-perms +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-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "coder-provisioner" +subjects: + - kind: ServiceAccount + name: "coder-provisioner" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-provisioner-workspace-perms +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + com.coder/annotation/baz: qux + com.coder/annotation/foo: bar + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + com.coder/label/baz: qux + com.coder/label/foo: bar + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder-provisioner + template: + metadata: + annotations: + com.coder/podAnnotation/baz: qux + com.coder/podAnnotation/foo: bar + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + com.coder/podLabel/baz: qux + com.coder/podLabel/foo: bar + helm.sh/chart: coder-provisioner-0.1.0 + spec: + containers: + - args: + - provisionerd + - start + command: + - /opt/coder + env: + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: coder-provisioner-psk + - name: CODER_URL + value: http://coder.default.svc.cluster.local + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + name: coder + ports: null + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder-provisioner + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/provisioner/tests/testdata/labels_annotations.yaml b/helm/provisioner/tests/testdata/labels_annotations.yaml new file mode 100644 index 0000000000000..a7ddda708be79 --- /dev/null +++ b/helm/provisioner/tests/testdata/labels_annotations.yaml @@ -0,0 +1,15 @@ +coder: + image: + tag: latest + annotations: + com.coder/annotation/foo: bar + com.coder/annotation/baz: qux + labels: + com.coder/label/foo: bar + com.coder/label/baz: qux + podAnnotations: + com.coder/podAnnotation/foo: bar + com.coder/podAnnotation/baz: qux + podLabels: + com.coder/podLabel/foo: bar + com.coder/podLabel/baz: qux diff --git a/helm/provisioner/tests/testdata/missing_values.yaml b/helm/provisioner/tests/testdata/missing_values.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/helm/provisioner/tests/testdata/provisionerd_psk.golden b/helm/provisioner/tests/testdata/provisionerd_psk.golden new file mode 100644 index 0000000000000..74a7ffbed4675 --- /dev/null +++ b/helm/provisioner/tests/testdata/provisionerd_psk.golden @@ -0,0 +1,137 @@ +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +--- +# Source: coder-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-provisioner-workspace-perms +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-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "coder-provisioner" +subjects: + - kind: ServiceAccount + name: "coder-provisioner" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-provisioner-workspace-perms +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder-provisioner + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + spec: + containers: + - args: + - provisionerd + - start + command: + - /opt/coder + env: + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: coder-provisionerd-psk + - name: CODER_PROVISIONERD_TAGS + value: clusterType=k8s,location=auh + - name: CODER_URL + value: http://coder.default.svc.cluster.local + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + name: coder + ports: null + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder-provisioner + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/provisioner/tests/testdata/provisionerd_psk.yaml b/helm/provisioner/tests/testdata/provisionerd_psk.yaml new file mode 100644 index 0000000000000..f891b007db539 --- /dev/null +++ b/helm/provisioner/tests/testdata/provisionerd_psk.yaml @@ -0,0 +1,8 @@ +coder: + image: + tag: latest +provisionerDaemon: + pskSecretName: "coder-provisionerd-psk" + tags: + location: auh + clusterType: k8s diff --git a/helm/provisioner/tests/testdata/sa.golden b/helm/provisioner/tests/testdata/sa.golden new file mode 100644 index 0000000000000..e5e2fd760d711 --- /dev/null +++ b/helm/provisioner/tests/testdata/sa.golden @@ -0,0 +1,136 @@ +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/coder-service-account + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-service-account +--- +# Source: coder-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: coder-service-account-workspace-perms +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-provisioner/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "coder-service-account" +subjects: + - kind: ServiceAccount + name: "coder-service-account" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: coder-service-account-workspace-perms +--- +# Source: coder-provisioner/templates/coder.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + name: coder-provisioner +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: coder-provisioner + template: + metadata: + annotations: {} + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: coder-provisioner + app.kubernetes.io/part-of: coder-provisioner + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: coder-provisioner-0.1.0 + spec: + containers: + - args: + - provisionerd + - start + command: + - /opt/coder + env: + - name: CODER_PROMETHEUS_ADDRESS + value: 0.0.0.0:2112 + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: coder-provisioner-psk + - name: CODER_URL + value: http://coder.default.svc.cluster.local + image: ghcr.io/coder/coder:latest + imagePullPolicy: IfNotPresent + lifecycle: {} + name: coder + ports: null + resources: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: null + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: [] + restartPolicy: Always + serviceAccountName: coder-service-account + terminationGracePeriodSeconds: 60 + volumes: [] diff --git a/helm/provisioner/tests/testdata/sa.yaml b/helm/provisioner/tests/testdata/sa.yaml new file mode 100644 index 0000000000000..4e0c98c223ae1 --- /dev/null +++ b/helm/provisioner/tests/testdata/sa.yaml @@ -0,0 +1,8 @@ +coder: + image: + tag: latest + serviceAccount: + name: coder-service-account + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/coder-service-account + workspacePerms: true diff --git a/helm/provisioner/values.yaml b/helm/provisioner/values.yaml new file mode 100644 index 0000000000000..08fb37a8bdd70 --- /dev/null +++ b/helm/provisioner/values.yaml @@ -0,0 +1,204 @@ +# coder -- Common configuration options. +coder: + # coder.env -- The environment variables to set. These can be used to + # configure all aspects of Coder provisioner daemon. Please see + # `coder provisionerd start --help for information about what environment + # variables can be set. + # Note: The following environment variables are set by default and cannot be + # overridden: + # - CODER_PROMETHEUS_ADDRESS: set to 0.0.0.0:2112 and cannot be changed. + # Prometheus must still be enabled by setting CODER_PROMETHEUS_ENABLE. + # + # We will additionally set CODER_URL, if unset, to the cluster service + # URL. + env: [] + # - name: "CODER_URL" + # value: "https://coder.example.com" + + # coder.image -- The image to use for Coder provisioner daemon. + image: + # coder.image.repo -- The repository of the image. + repo: "ghcr.io/coder/coder" + # coder.image.tag -- The tag of the image, defaults to {{.Chart.AppVersion}} + # if not set. If you're using the chart directly from git, the default + # app version will not work and you'll need to set this value. The helm + # chart helpfully fails quickly in this case. + tag: "" + # coder.image.pullPolicy -- The pull policy to use for the image. See: + # https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy + pullPolicy: IfNotPresent + # coder.image.pullSecrets -- The secrets used for pulling the Coder image from + # a private registry. + pullSecrets: [] + # - name: "pull-secret" + + # coder.initContainers -- Init containers for the deployment. See: + # https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + initContainers: + [] + # - name: init-container + # image: busybox:1.28 + # command: ['sh', '-c', "sleep 2"] + + # coder.annotations -- The Deployment annotations. See: + # https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + annotations: {} + + # coder.labels -- The Deployment labels. See: + # https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + labels: {} + + # coder.podAnnotations -- The Coder pod annotations. See: + # https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + podAnnotations: {} + + # coder.podLabels -- The Coder pod labels. See: + # https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + + # coder.serviceAccount -- Configuration for the automatically created service + # account. Creation of the service account cannot be disabled. + serviceAccount: + # coder.serviceAccount.workspacePerms -- Whether or not to grant the + # service account permissions to manage workspaces. This includes + # permission to manage pods and persistent volume claims in the deployment + # namespace. + # + # It is recommended to keep this on if you are using Kubernetes templates + # within Coder. + workspacePerms: true + # coder.serviceAccount.enableDeployments -- Provides the service account permission + # to manage Kubernetes deployments. + enableDeployments: true + # coder.serviceAccount.annotations -- The Coder service account annotations. + annotations: {} + # coder.serviceAccount.name -- The service account name + name: coder-provisioner + + # coder.securityContext -- Fields related to the container's security + # context (as opposed to the pod). Some fields are also present in the pod + # security context, in which case these values will take precedence. + securityContext: + # coder.securityContext.runAsNonRoot -- Requires that the coder container + # runs as an unprivileged user. If setting runAsUser to 0 (root), this + # will need to be set to false. + runAsNonRoot: true + # coder.securityContext.runAsUser -- Sets the user id of the container. + # For security reasons, we recommend using a non-root user. + runAsUser: 1000 + # coder.securityContext.runAsGroup -- Sets the group id of the container. + # For security reasons, we recommend using a non-root group. + runAsGroup: 1000 + # coder.securityContext.readOnlyRootFilesystem -- Mounts the container's + # root filesystem as read-only. + readOnlyRootFilesystem: null + # coder.securityContext.seccompProfile -- Sets the seccomp profile for + # the coder container. + seccompProfile: + type: RuntimeDefault + # coder.securityContext.allowPrivilegeEscalation -- Controls whether + # the container can gain additional privileges, such as escalating to + # root. It is recommended to leave this setting disabled in production. + allowPrivilegeEscalation: false + + # coder.volumes -- A list of extra volumes to add to the Coder provisioner daemon pod. + volumes: [] + # - name: "my-volume" + # emptyDir: {} + + # coder.volumeMounts -- A list of extra volume mounts to add to the Coder provisioner daemon pod. + volumeMounts: [] + # - name: "my-volume" + # mountPath: "/mnt/my-volume" + + # coder.replicaCount -- The number of Kubernetes deployment replicas. This + # should only be increased if High Availability is enabled. + # + # This is an Enterprise feature. Contact sales@coder.com. + replicaCount: 1 + + # coder.lifecycle -- container lifecycle handlers for the Coder container, allowing + # for lifecycle events such as postStart and preStop events + # See: https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/ + lifecycle: + {} + # postStart: + # exec: + # command: ["/bin/sh", "-c", "echo postStart"] + # preStop: + # exec: + # command: ["/bin/sh","-c","echo preStart"] + + # coder.resources -- The resources to request for Coder. These are optional + # and are not set by default. + resources: + {} + # limits: + # cpu: 2000m + # memory: 4096Mi + # requests: + # cpu: 2000m + # memory: 4096Mi + + # coder.certs -- CA bundles to mount inside the Coder pod. + certs: + # coder.certs.secrets -- A list of CA bundle secrets to mount into the + # pod. The secrets should exist in the same namespace as the Helm + # deployment. + # + # The given key in each secret is mounted at + # `/etc/ssl/certs/{secret_name}.crt`. + secrets: + [] + # - name: "my-ca-bundle" + # key: "ca-bundle.crt" + + # coder.affinity -- Allows specifying an affinity rule for the deployment. + affinity: + {} + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - podAffinityTerm: + # labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - "coder" + # topologyKey: kubernetes.io/hostname + # weight: 1 + + # coder.tolerations -- Tolerations for tainted nodes. + # See: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: + {} + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + + # coder.nodeSelector -- Node labels for constraining coder pods to nodes. + # See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} + # kubernetes.io/os: linux + + # coder.command -- The command to use when running the container. Used + # for customizing the location of the `coder` binary in your image. + command: + - /opt/coder + + # coder.commandArgs -- Set arguments for the entrypoint command of the Coder pod. + commandArgs: [] + +# provisionerDaemon -- Provisioner Daemon configuration options +provisionerDaemon: + # provisionerDaemon.pskSecretName -- The name of the Kubernetes secret that contains the + # Pre-Shared Key (PSK) to use to authenticate with Coder. The secret must be in the same namespace + # as the Helm deployment, and contain an item called "psk" which contains the pre-shared key. + pskSecretName: "coder-provisioner-psk" + + # provisionerDaemon.tags -- Tags to filter provisioner jobs by + tags: + {} + # location: usa + # provider: kubernetes diff --git a/helm/templates/coder.yaml b/helm/templates/coder.yaml deleted file mode 100644 index 09b284e676bc8..0000000000000 --- a/helm/templates/coder.yaml +++ /dev/null @@ -1,143 +0,0 @@ -{{- include "coder.verifyDeprecated" . -}} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Values.coder.serviceAccount.name | quote }} - annotations: {{ toYaml .Values.coder.serviceAccount.annotations | nindent 4 }} - labels: - {{- include "coder.labels" . | nindent 4 }} ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: coder - labels: - {{- include "coder.labels" . | nindent 4 }} - {{- with .Values.coder.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - annotations: {{ toYaml .Values.coder.annotations | nindent 4}} -spec: - replicas: {{ .Values.coder.replicaCount }} - selector: - matchLabels: - {{- include "coder.selectorLabels" . | nindent 6 }} - template: - metadata: - labels: - {{- include "coder.labels" . | nindent 8 }} - {{- with .Values.coder.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - annotations: - {{- toYaml .Values.coder.podAnnotations | nindent 8 }} - spec: - serviceAccountName: {{ .Values.coder.serviceAccount.name | quote }} - restartPolicy: Always - {{- with .Values.coder.image.pullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 60 - {{- with .Values.coder.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.coder.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.coder.nodeSelector }} - nodeSelector: - {{ toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.coder.initContainers }} - initContainers: - {{ toYaml . | nindent 8 }} - {{- end }} - containers: - - name: coder - image: {{ include "coder.image" . | quote }} - imagePullPolicy: {{ .Values.coder.image.pullPolicy }} - command: - {{- toYaml .Values.coder.command | nindent 12 }} - args: - {{- if .Values.coder.commandArgs }} - {{- toYaml .Values.coder.commandArgs | nindent 12 }} - {{- else }} - {{- if .Values.coder.workspaceProxy }} - - wsproxy - {{- end }} - - server - {{- end }} - resources: - {{- toYaml .Values.coder.resources | nindent 12 }} - lifecycle: - {{- toYaml .Values.coder.lifecycle | nindent 12 }} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - {{- $hasAccessURL := false }} - {{- range .Values.coder.env }} - {{- if eq .name "CODER_ACCESS_URL" }} - {{- $hasAccessURL = true }} - {{- end }} - {{- end }} - {{- if not $hasAccessURL }} - - name: CODER_ACCESS_URL - value: {{ include "coder.defaultAccessURL" . | quote }} - {{- end }} - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - {{- include "coder.tlsEnv" . | nindent 12 }} - {{- with .Values.coder.env -}} - {{ toYaml . | nindent 12 }} - {{- end }} - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - {{- if eq (include "coder.tlsEnabled" .) "true" }} - - name: "https" - containerPort: 8443 - protocol: TCP - {{- end }} - {{- range .Values.coder.env }} - {{- if eq .name "CODER_PROMETHEUS_ENABLE" }} - {{/* - This sadly has to be nested to avoid evaluating the second part - of the condition too early and potentially getting type errors if - the value is not a string (like a `valueFrom`). We do not support - `valueFrom` for this env var specifically. - */}} - {{- if eq .value "true" }} - - name: "prometheus-http" - containerPort: 2112 - protocol: TCP - {{- end }} - {{- end }} - {{- end }} - securityContext: {{ toYaml .Values.coder.securityContext | nindent 12 }} - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - {{- include "coder.volumeMounts" . | nindent 10 }} - - {{- include "coder.volumes" . | nindent 6 }} diff --git a/helm/tests/testdata/tls.golden b/helm/tests/testdata/tls.golden deleted file mode 100644 index 8ef85d138f722..0000000000000 --- a/helm/tests/testdata/tls.golden +++ /dev/null @@ -1,220 +0,0 @@ ---- -# Source: coder/templates/coder.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: "coder" - annotations: - {} - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm ---- -# Source: coder/templates/rbac.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: coder-workspace-perms -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" -subjects: - - kind: ServiceAccount - name: "coder" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: coder-workspace-perms ---- -# Source: coder/templates/service.yaml -apiVersion: v1 -kind: Service -metadata: - name: coder - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm - annotations: - {} -spec: - type: LoadBalancer - sessionAffinity: ClientIP - ports: - - name: "http" - port: 80 - targetPort: "http" - protocol: TCP - - name: "https" - port: 443 - targetPort: "https" - protocol: TCP - externalTrafficPolicy: "Cluster" - selector: - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name ---- -# Source: coder/templates/coder.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: coder - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm - annotations: - {} -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - template: - metadata: - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm - annotations: - {} - spec: - serviceAccountName: "coder" - restartPolicy: Always - terminationGracePeriodSeconds: 60 - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - podAffinityTerm: - labelSelector: - matchExpressions: - - key: app.kubernetes.io/instance - operator: In - values: - - coder - topologyKey: kubernetes.io/hostname - weight: 1 - containers: - - name: coder - image: "ghcr.io/coder/coder:latest" - imagePullPolicy: IfNotPresent - command: - - /opt/coder - args: - - server - resources: - {} - lifecycle: - {} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - - name: CODER_ACCESS_URL - value: "https://coder.default.svc.cluster.local" - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - - - name: CODER_TLS_ENABLE - value: "true" - - name: CODER_TLS_ADDRESS - value: "0.0.0.0:8443" - - name: CODER_TLS_CERT_FILE - value: "/etc/ssl/certs/coder/coder-tls/tls.crt" - - name: CODER_TLS_KEY_FILE - value: "/etc/ssl/certs/coder/coder-tls/tls.key" - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - - name: "https" - containerPort: 8443 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: null - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - volumeMounts: - - name: "tls-coder-tls" - mountPath: "/etc/ssl/certs/coder/coder-tls" - readOnly: true - - volumes: - - name: "tls-coder-tls" - secret: - secretName: "coder-tls" diff --git a/helm/tests/testdata/workspace_proxy.golden b/helm/tests/testdata/workspace_proxy.golden deleted file mode 100644 index 88e0213be559d..0000000000000 --- a/helm/tests/testdata/workspace_proxy.golden +++ /dev/null @@ -1,206 +0,0 @@ ---- -# Source: coder/templates/coder.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: "coder" - annotations: - {} - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm ---- -# Source: coder/templates/rbac.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: coder-workspace-perms -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" -subjects: - - kind: ServiceAccount - name: "coder" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: coder-workspace-perms ---- -# Source: coder/templates/service.yaml -apiVersion: v1 -kind: Service -metadata: - name: coder - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm - annotations: - {} -spec: - type: LoadBalancer - sessionAffinity: ClientIP - ports: - - name: "http" - port: 80 - targetPort: "http" - protocol: TCP - externalTrafficPolicy: "Cluster" - selector: - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name ---- -# Source: coder/templates/coder.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: coder - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm - annotations: - {} -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - template: - metadata: - labels: - helm.sh/chart: coder-0.1.0 - app.kubernetes.io/name: coder - app.kubernetes.io/instance: release-name - app.kubernetes.io/part-of: coder - app.kubernetes.io/version: "0.1.0" - app.kubernetes.io/managed-by: Helm - annotations: - {} - spec: - serviceAccountName: "coder" - restartPolicy: Always - terminationGracePeriodSeconds: 60 - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - podAffinityTerm: - labelSelector: - matchExpressions: - - key: app.kubernetes.io/instance - operator: In - values: - - coder - topologyKey: kubernetes.io/hostname - weight: 1 - containers: - - name: coder - image: "ghcr.io/coder/coder:latest" - imagePullPolicy: IfNotPresent - command: - - /opt/coder - args: - - wsproxy - - server - resources: - {} - lifecycle: - {} - env: - - name: CODER_HTTP_ADDRESS - value: "0.0.0.0:8080" - - name: CODER_PROMETHEUS_ADDRESS - value: "0.0.0.0:2112" - # Set the default access URL so a `helm apply` works by default. - # See: https://github.com/coder/coder/issues/5024 - - name: CODER_ACCESS_URL - value: "http://coder.default.svc.cluster.local" - # Used for inter-pod communication with high-availability. - - name: KUBE_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: CODER_DERP_SERVER_RELAY_URL - value: "http://$(KUBE_POD_IP):8080" - - - name: CODER_PRIMARY_ACCESS_URL - value: https://dev.coder.com - - name: CODER_PROXY_SESSION_TOKEN - valueFrom: - secretKeyRef: - key: token - name: coder-workspace-proxy-session-token - ports: - - name: "http" - containerPort: 8080 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: null - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - readinessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - livenessProbe: - httpGet: - path: /healthz - port: "http" - scheme: "HTTP" - volumeMounts: [] - volumes: [] diff --git a/provisionerd/provisionerd.go b/provisionerd/provisionerd.go index d7e50f96bfab1..78ea5f5c29ad2 100644 --- a/provisionerd/provisionerd.go +++ b/provisionerd/provisionerd.go @@ -204,7 +204,7 @@ func (p *Server) connect(ctx context.Context) { p.clientValue.Store(ptr.Ref(client)) p.mutex.Unlock() - p.opts.Logger.Debug(context.Background(), "connected") + p.opts.Logger.Info(ctx, "provisionerd successfully connected to coderd") break } select { diff --git a/scripts/helm.sh b/scripts/helm.sh index 33b556f0100a1..67edad0e149fc 100755 --- a/scripts/helm.sh +++ b/scripts/helm.sh @@ -69,7 +69,9 @@ cdroot temp_dir="$(mktemp -d)" cdroot -cd ./helm +cd ./helm/coder +log "--- Updating dependencies" +helm dependency update . log "--- Packaging helm chart for version $version ($output_path)" helm package \ --version "$version" \ diff --git a/site/.eslintignore b/site/.eslintignore index 46023d091348a..9bed2be372b11 100644 --- a/site/.eslintignore +++ b/site/.eslintignore @@ -67,7 +67,7 @@ stats/ # .prettierignore.include: # Helm templates contain variables that are invalid YAML and can't be formatted # by Prettier. -../helm/templates/*.yaml +../helm/**/templates/*.yaml # Terraform state files used in tests, these are automatically generated. # Example: provisioner/terraform/testdata/instance-id/instance-id.tfstate.json diff --git a/site/.prettierignore b/site/.prettierignore index 46023d091348a..9bed2be372b11 100644 --- a/site/.prettierignore +++ b/site/.prettierignore @@ -67,7 +67,7 @@ stats/ # .prettierignore.include: # Helm templates contain variables that are invalid YAML and can't be formatted # by Prettier. -../helm/templates/*.yaml +../helm/**/templates/*.yaml # Terraform state files used in tests, these are automatically generated. # Example: provisioner/terraform/testdata/instance-id/instance-id.tfstate.json