diff --git a/charts/sourcegraph-executor/k8s/README.md b/charts/sourcegraph-executor/k8s/README.md index 1b5905a9..14b0fdff 100644 --- a/charts/sourcegraph-executor/k8s/README.md +++ b/charts/sourcegraph-executor/k8s/README.md @@ -84,6 +84,10 @@ In addition to the documented values, the `executor` and `private-docker-registr | executor.kubernetesJob.resources.requests.memory | string | `"1Gi"` | The requested memory for a job. | | executor.kubernetesJob.runAsGroup | int | `nil`; accepts [0, 2147483647] | The group ID to run Kubernetes jobs as. | | executor.kubernetesJob.runAsUser | int | `nil`; accepts [0, 2147483647] | The user ID to run Kubernetes jobs as. | +| executor.kubernetesJob.serviceAccount.annotations | object | `{}` | Annotations to add to the created ServiceAccount | +| executor.kubernetesJob.serviceAccount.automountToken | bool | `false` | Mount the ServiceAccount token into job pods. Jobs only talk to the Sourcegraph frontend and never need the Kubernetes API. Applied on both the created ServiceAccount and, on executor images that include sourcegraph/sourcegraph#16392, the job pod spec. | +| executor.kubernetesJob.serviceAccount.create | bool | `true` | Create a ServiceAccount for job pods, with no RBAC bindings. Rendered only when `executor.configureRbac` is also true, so a second executor release in the same namespace does not try to own it. Set to false to use an existing ServiceAccount named by `executor.kubernetesJob.serviceAccount.name`. | +| executor.kubernetesJob.serviceAccount.name | string | `"sg-executor-job"` | The ServiceAccount job pods run as. Created in `executor.namespace`, where the job pods run. Empty falls back to the namespace `default` ServiceAccount. Requires an executor image that includes sourcegraph/sourcegraph#16392; older executors ignore this setting. | | executor.log.format | string | `"condensed"` | | | executor.log.level | string | `"warn"` | Possible values are `dbug`, `info`, `warn`, `eror`, `crit`. | | executor.log.trace | string | `"false"` | | diff --git a/charts/sourcegraph-executor/k8s/templates/executor.ConfigMap.yaml b/charts/sourcegraph-executor/k8s/templates/executor.ConfigMap.yaml index 6e773607..a4e639dd 100644 --- a/charts/sourcegraph-executor/k8s/templates/executor.ConfigMap.yaml +++ b/charts/sourcegraph-executor/k8s/templates/executor.ConfigMap.yaml @@ -37,6 +37,8 @@ data: KUBERNETES_RUN_AS_USER: "{{ .Values.executor.kubernetesJob.runAsUser }}" KUBERNETES_RUN_AS_GROUP: "{{ .Values.executor.kubernetesJob.runAsGroup }}" KUBERNETES_FS_GROUP: "{{ .Values.executor.kubernetesJob.fsGroup }}" + KUBERNETES_JOB_SERVICE_ACCOUNT_NAME: "{{ .Values.executor.kubernetesJob.serviceAccount.name }}" + KUBERNETES_JOB_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN: "{{ .Values.executor.kubernetesJob.serviceAccount.automountToken }}" EXECUTOR_DOCKER_ADD_HOST_GATEWAY: "{{.Values.executor.dockerAddHostGateway }}" KUBERNETES_KEEP_JOBS: "{{ .Values.executor.debug.keepJobs }}" diff --git a/charts/sourcegraph-executor/k8s/templates/executor.JobServiceAccount.yaml b/charts/sourcegraph-executor/k8s/templates/executor.JobServiceAccount.yaml new file mode 100644 index 00000000..ecad3c94 --- /dev/null +++ b/charts/sourcegraph-executor/k8s/templates/executor.JobServiceAccount.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.executor.configureRbac .Values.executor.kubernetesJob.serviceAccount.create .Values.executor.kubernetesJob.serviceAccount.name }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.executor.kubernetesJob.serviceAccount.name }} + namespace: {{ .Values.executor.namespace }} + labels: + category: rbac + deploy: sourcegraph + sourcegraph-resource-requires: cluster-admin + app.kubernetes.io/component: executor +{{- with .Values.executor.kubernetesJob.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +automountServiceAccountToken: {{ .Values.executor.kubernetesJob.serviceAccount.automountToken }} +{{- end }} diff --git a/charts/sourcegraph-executor/k8s/tests/executor_test.yaml b/charts/sourcegraph-executor/k8s/tests/executor_test.yaml index 256638de..a65425da 100644 --- a/charts/sourcegraph-executor/k8s/tests/executor_test.yaml +++ b/charts/sourcegraph-executor/k8s/tests/executor_test.yaml @@ -3,6 +3,7 @@ templates: - executor.Deployment.yaml - executor.Service.yaml - executor.ConfigMap.yaml + - executor.JobServiceAccount.yaml tests: - it: should render the Deployment, Service, ConfigMap if executor is enabled set: @@ -125,3 +126,104 @@ tests: path: spec.template.spec.securityContext.runAsUser - isNull: path: spec.template.spec.securityContext.runAsGroup + + - it: should render the job ServiceAccount without a token mount by default + template: executor.JobServiceAccount.yaml + set: + executor: + queueName: "test" + asserts: + - containsDocument: + kind: ServiceAccount + apiVersion: v1 + name: sg-executor-job + - equal: + path: automountServiceAccountToken + value: false + - isNull: + path: metadata.annotations + + - it: should create the job ServiceAccount in the job namespace + template: executor.JobServiceAccount.yaml + set: + executor: + queueName: "test" + namespace: sourcegraph-executor-jobs + asserts: + - equal: + path: metadata.namespace + value: sourcegraph-executor-jobs + + - it: should pass the job ServiceAccount settings to the executor by default + template: executor.ConfigMap.yaml + set: + executor: + queueName: "test" + asserts: + - equal: + path: data.KUBERNETES_JOB_SERVICE_ACCOUNT_NAME + value: sg-executor-job + - equal: + path: data.KUBERNETES_JOB_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN + value: "false" + + - it: should not render the job ServiceAccount when configureRbac is false + template: executor.JobServiceAccount.yaml + set: + executor: + queueName: "test" + configureRbac: false + asserts: + - hasDocuments: + count: 0 + + - it: should not render the job ServiceAccount when create is false but still pass the name + set: + executor: + queueName: "test" + kubernetesJob: + serviceAccount: + create: false + name: my-existing-job-sa + asserts: + - hasDocuments: + count: 0 + template: executor.JobServiceAccount.yaml + - equal: + path: data.KUBERNETES_JOB_SERVICE_ACCOUNT_NAME + value: my-existing-job-sa + template: executor.ConfigMap.yaml + + - it: should fall back to the namespace default ServiceAccount when name is empty + set: + executor: + queueName: "test" + kubernetesJob: + serviceAccount: + name: "" + asserts: + - hasDocuments: + count: 0 + template: executor.JobServiceAccount.yaml + - equal: + path: data.KUBERNETES_JOB_SERVICE_ACCOUNT_NAME + value: "" + template: executor.ConfigMap.yaml + + - it: should render job ServiceAccount annotations and token mount when set + template: executor.JobServiceAccount.yaml + set: + executor: + queueName: "test" + kubernetesJob: + serviceAccount: + automountToken: true + annotations: + iam.gke.io/gcp-service-account: jobs@example.iam.gserviceaccount.com + asserts: + - equal: + path: metadata.annotations["iam.gke.io/gcp-service-account"] + value: jobs@example.iam.gserviceaccount.com + - equal: + path: automountServiceAccountToken + value: true diff --git a/charts/sourcegraph-executor/k8s/values.yaml b/charts/sourcegraph-executor/k8s/values.yaml index 0bc1320e..923878bb 100644 --- a/charts/sourcegraph-executor/k8s/values.yaml +++ b/charts/sourcegraph-executor/k8s/values.yaml @@ -100,6 +100,15 @@ executor: runAsGroup: # -- The group ID which is set on the job PVC file system. fsGroup: "1000" + serviceAccount: + # -- Create a ServiceAccount for job pods, with no RBAC bindings. Rendered only when `executor.configureRbac` is also true, so a second executor release in the same namespace does not try to own it. Set to false to use an existing ServiceAccount named by `executor.kubernetesJob.serviceAccount.name`. + create: true + # -- The ServiceAccount job pods run as. Created in `executor.namespace`, where the job pods run. Empty falls back to the namespace `default` ServiceAccount. Requires an executor image that includes sourcegraph/sourcegraph#16392; older executors ignore this setting. + name: sg-executor-job + # -- Annotations to add to the created ServiceAccount + annotations: { } + # -- Mount the ServiceAccount token into job pods. Jobs only talk to the Sourcegraph frontend and never need the Kubernetes API. Applied on both the created ServiceAccount and, on executor images that include sourcegraph/sourcegraph#16392, the job pod spec. + automountToken: false resources: requests: # -- The requested CPU for a job.