diff --git a/.gitignore b/.gitignore index b39e122..8c2ea68 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ .iml **/tests/__snapshot__/ + +.serena/cache/ +reviews/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..ab7dbf1 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,89 @@ +# Gremlin Helm Charts — Repo Conventions + +## Reserved-name collisions must fail fast + +Any *new* chart value that lets a user **define** a named Kubernetes fragment alongside +chart-managed resources of the same kind — `extraVolumes`, `extraVolumeMounts`, `initContainers`, +and any future value of this shape — must fail the template render (via a `_validation.tpl`-style +`fail` check, included at the top of the resource template) when the user-supplied name collides +with a name the chart itself already owns. + +This does not apply retroactively to `extraEnv`. It's pre-existing, and `extraEnv` renders last in +both containers' `env:` lists, so a collision there is Kubernetes' documented last-wins override +behavior — a real, working use case (e.g. overriding `GREMLIN_SERVICE_URL` or `https_proxy`), not +a bug. Retrofitting a hard failure onto it would break existing installs on their next +`helm upgrade` with no opt-in. + +This also does not apply to `envFrom`: it *references* an existing ConfigMap/Secret by name rather +than defining a new object, and the chart cannot see that object's keys at render time, so there +is nothing to statically collide-check. + +**The DaemonSet and Chao Deployment each get their own reserved list, not one shared list.** They +render different chart-managed resources, and checking a workload's `extraVolumes`/`initContainers` +against the *other* workload's names produces false rejections (Chao doesn't render `gremlin-state`, +the DaemonSet doesn't render `chao-tls-identity`, and so on). + +Reserved names as of this writing: + +- DaemonSet volumes: `gremlin-state`, `gremlin-executions`, `gremlin-logs`, `cgroup-root`, + `seccomp-root`, `seccomp-profile`, `gremlin-cert`, `ssl-cert-file`, `gremlin-tls-identity`, + `gremlin-opencl-icd`, `kfd`, `dri`, `opencl-vendors`, plus the container-driver socket volumes + (derived from `.Values.containerDrivers.*.name` at render time, not hardcoded — currently + `docker-sock`, `containerd-sock`, `crio-sock`). +- DaemonSet container names (for `initContainers`): `seccomp-init`, `gremlin`. +- Chao volumes: `gremlin-cert`, `ssl-cert-file`, `chao-tls-identity`. +- Chao container names (for `initContainers`): `chao`. +- Env vars (not currently checked — see `envFrom`/`extraEnv` above): `GREMLIN_TEAM_ID`, + `GREMLIN_TEAM_SECRET`, `GREMLIN_TEAM_CERTIFICATE_OR_FILE`, `GREMLIN_TEAM_PRIVATE_KEY_OR_FILE`, + `GREMLIN_IDENTIFIER`, `GREMLIN_CLIENT_TAGS`, `GREMLIN_COLLECT_DNS`, `GREMLIN_SERVICE_URL`, + `GREMLIN_PUSH_POD_CIDR_TAGS`, `GREMLIN_PUSH_ZONE_CIDR_TAGS`, `https_proxy`, `no_proxy`, + `SSL_CERT_FILE`, `SSL_CERT_DIR`, `GREMLIN_TLS_IDENTITY_CERTIFICATE`, + `GREMLIN_TLS_IDENTITY_PRIVATE_KEY`, `GREMLIN_CLUSTER_ID`, and any GPU vendor env vars (e.g. + `NVIDIA_VISIBLE_DEVICES`, `NVIDIA_DRIVER_CAPABILITIES`). + +**Why:** a silent name collision either gets rejected by the Kubernetes API with an opaque error, +or silently shadows/duplicates a chart-managed resource — both are worse than a clear failure at +`helm template`/`helm install` time naming the conflicting value path. + +**How to apply:** whenever a new chart value accepts user-supplied names in this shape, add its +name to the correct workload's reserved list (`gremlin.reservedNames.daemonset*` / +`.chao*` in `_validation.tpl`) and to this file's list above. Prefer deriving a reserved name from +its source value (as the container-driver sockets do) over hardcoding it, when the source is a +small, fixed-shape values block — hardcoding only the GPU vendor gap below because that block's +shape is genuinely open-ended. + +**Known gap:** `gremlin.gpu.` blocks are still static. A hand-configured vendor's +`volumes`/`volumeMounts` entries are not covered by the check — a collision there surfaces only as +a Kubernetes API rejection at apply time, not a chart-level failure. Whoever adds a vendor block +should add its names to the reserved list above. + +## Name test files after the behavior, not the ticket + +`gremlin/tests/*.yaml` files (and their `suite:` descriptions) describe what they test, not which +ticket introduced them — e.g. `extra_volumes_test.yaml` / `suite: extraVolumes / extraVolumeMounts`, +not `en-12345_extra_volumes_test.yaml` / `suite: EN-12345 - extraVolumes`. + +**Why:** a ticket ID tells a future reader nothing about what broke, and outlives its usefulness +the moment the ticket is closed — the test itself is what has to stay legible. + +**How to apply:** when adding tests for a ticket, name the file and suite for the behavior under +test, matching the existing style (`daemonset_resources_test.yaml`, +`chao_deployment_namespaces_test.yaml`, ...). Keep ticket context in the commit message and PR +description instead. + +## Don't reference internal tickets or design docs in repo-committed files + +This repo (and this file) is public-facing. Don't cite a Jira ticket key, an internal contract +slug, or a path like `.claude/contracts//design.md` in `CLAUDE.md`, `README.md`, code +comments, or `values.yaml` doc comments — describe the reasoning in prose instead of pointing at +where it was decided. + +**Why:** a ticket or internal-tooling reference is meaningless to anyone outside the team, and it +rots the moment that tooling's working state is cleaned up or the ticket is closed — a design +rationale should stand on its own, not depend on a link that may not resolve for the reader, or at +all. + +**How to apply:** when explaining *why* a decision was made, restate the reasoning directly (as +this file already does above for the `extraEnv` exemption). Ticket numbers and links to +in-progress design artifacts belong in the commit message and PR description, not in +repo-committed files. diff --git a/gremlin/README.md b/gremlin/README.md index b96e65d..1f1ae14 100644 --- a/gremlin/README.md +++ b/gremlin/README.md @@ -35,6 +35,18 @@ their default values. See values.yaml for all available options. | `nodeSelector` | Map of node labels for pod assignment for the `gremlin` container | `{}` | | `tolerations` | List of node taints to tolerate for the `gremlin` container | `[]` | | `affinity` | Map of node/pod affinities for the `gremlin` container | `{}` | +| `livenessProbe` | A Kubernetes `Probe` for the `gremlin` container | `{}` | +| `readinessProbe` | A Kubernetes `Probe` for the `gremlin` container | `{}` | +| `startupProbe` | A Kubernetes `Probe` for the `gremlin` container | `{}` | +| `initContainers` | Additional init containers for the `gremlin` DaemonSet, appended after `seccomp-init` when enabled. A name colliding with one the chart manages fails the install | `[]` | +| `extraVolumes` | Additional volumes for the `gremlin` DaemonSet. A name colliding with one the chart manages fails the install | `[]` | +| `extraVolumeMounts` | Additional volume mounts for the `gremlin` container. A name colliding with one the chart manages fails the install | `[]` | +| `lifecycle` | A Kubernetes `Lifecycle` object (`preStop`/`postStart`) for the `gremlin` container | `{}` | +| `envFrom` | Additional `ConfigMap`/`Secret` sources for the `gremlin` container's environment. Unlike `gremlin.extraEnv`, does not override chart-managed env vars (Kubernetes gives `env:` precedence over `envFrom:`) | `[]` | +| `terminationGracePeriodSeconds` | Termination grace period, in seconds, for the `gremlin` DaemonSet's pods | (Kubernetes default: `30`) | +| `dnsConfig` | A Kubernetes `PodDNSConfig` for the `gremlin` DaemonSet's pod spec | `{}` | +| `hostAliases` | A list of Kubernetes `HostAlias` entries for the `gremlin` DaemonSet's pod spec. No effect while `gremlin.hostNetwork` is `true` (the default) | `[]` | +| `podSecurityContext` | A Kubernetes pod-level `SecurityContext` for the `gremlin` DaemonSet, alongside the existing container-level `gremlin.podSecurity.*` settings | `{}` | | `chao.podLabels` | Kubernetes labels applied to the chao deployment and it's Pods | `{}` | | `chao.priorityClassName` | The name of the priority class to use for the Chao deployment | `""` | | `chao.nodeSelector` | Map of node labels for pod assignment for the `chao` container | `{}` | @@ -43,6 +55,18 @@ their default values. See values.yaml for all available options. | `chao.create` | Enable kubernetes targeting by installing k8s client | true | | `chao.resources` | Set resource requests and limits for the chao deployment | `{}` | | `chao.extraEnv` | Specify any arbitrary environment variables to pass to the Chao deployment. | `[]` | +| `chao.livenessProbe` | A Kubernetes `Probe` for the `chao` container | `{}` | +| `chao.readinessProbe` | A Kubernetes `Probe` for the `chao` container | `{}` | +| `chao.startupProbe` | A Kubernetes `Probe` for the `chao` container | `{}` | +| `chao.initContainers` | Additional init containers for the `chao` deployment. A name colliding with one the chart manages fails the install | `[]` | +| `chao.extraVolumes` | Additional volumes for the `chao` deployment. A name colliding with one the chart manages fails the install | `[]` | +| `chao.extraVolumeMounts` | Additional volume mounts for the `chao` container. A name colliding with one the chart manages fails the install | `[]` | +| `chao.lifecycle` | A Kubernetes `Lifecycle` object (`preStop`/`postStart`) for the `chao` container | `{}` | +| `chao.envFrom` | Additional `ConfigMap`/`Secret` sources for the `chao` container's environment. Unlike `chao.extraEnv`, does not override chart-managed env vars (Kubernetes gives `env:` precedence over `envFrom:`) | `[]` | +| `chao.terminationGracePeriodSeconds` | Termination grace period, in seconds, for the `chao` deployment's pods | (Kubernetes default: `30`) | +| `chao.dnsConfig` | A Kubernetes `PodDNSConfig` for the `chao` deployment's pod spec | `{}` | +| `chao.hostAliases` | A list of Kubernetes `HostAlias` entries for the `chao` deployment's pod spec | `[]` | +| `chao.podSecurityContext` | A Kubernetes pod-level `SecurityContext` for the `chao` deployment's pod spec | `{}` | | `chao.namespaces` | List of namespaces for Gremlin to watch for attacking | `[]` | | `chao.excludedNamespaces` | List of namespaces Gremlin should never report or attack (mutually exclusive with `chao.namespaces`) | `[]` | | `chao.features.dynamicQuery.enabled` | Let Gremlin query Kubernetes resources beyond the fixed set Chao watches by default. [See below](#chao-dynamic-queries) | `false` | diff --git a/gremlin/templates/_daemonset.tpl b/gremlin/templates/_daemonset.tpl index 04692cc..531d6f6 100644 --- a/gremlin/templates/_daemonset.tpl +++ b/gremlin/templates/_daemonset.tpl @@ -21,6 +21,7 @@ Context: dict {{- /* CDI device: global gremlin.gpu.cdiDevice, optionally overridden per vendor block */ -}} {{- $cdiDevice := "" -}} {{- with $gpu -}}{{- $cdiDevice = default $root.Values.gremlin.gpu.cdiDevice .cdiDevice -}}{{- end -}} +{{- $seccompInit := and $root.Values.gremlin.podSecurity.seccomp.enabled (eq "localhost/gremlin" $root.Values.gremlin.podSecurity.seccomp.profile) -}} apiVersion: apps/v1 kind: DaemonSet metadata: @@ -100,12 +101,25 @@ spec: dnsPolicy: {{ $root.Values.gremlin.dnsPolicy }} hostPID: {{ $root.Values.gremlin.hostPID }} hostNetwork: {{ $root.Values.gremlin.hostNetwork }} + {{- if not (kindIs "invalid" $root.Values.terminationGracePeriodSeconds) }} + terminationGracePeriodSeconds: {{ $root.Values.terminationGracePeriodSeconds | toJson }} + {{- end }} + {{- with $root.Values.dnsConfig }} + dnsConfig: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with $root.Values.hostAliases }} + hostAliases: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with $root.Values.podSecurityContext }} + securityContext: {{ toYaml . | nindent 8 }} + {{- end }} {{- if $root.Values.image.pullSecret }} imagePullSecrets: - name: {{ $root.Values.image.pullSecret }} {{- end }} - {{- if and $root.Values.gremlin.podSecurity.seccomp.enabled (eq "localhost/gremlin" $root.Values.gremlin.podSecurity.seccomp.profile) }} + {{- if or $seccompInit $root.Values.initContainers }} initContainers: + {{- if $seccompInit }} - name: seccomp-init image: {{ $root.Values.image.repository }}:{{ $root.Values.image.tag }} imagePullPolicy: {{ $root.Values.image.pullPolicy }} @@ -118,6 +132,10 @@ spec: - cp - /gremlin/seccomp.json - {{ $root.Values.gremlin.podSecurity.seccomp.root }}/gremlin + {{- end }} + {{- with $root.Values.initContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- end }} containers: - name: {{ $root.Chart.Name }} @@ -207,6 +225,21 @@ spec: {{- with $root.Values.gremlin.extraEnv }} {{- toYaml . | nindent 10 }} {{- end }} + {{- with $root.Values.envFrom }} + envFrom: {{ toYaml . | nindent 10 }} + {{- end }} + {{- with $root.Values.livenessProbe }} + livenessProbe: {{ toYaml . | nindent 10 }} + {{- end }} + {{- with $root.Values.readinessProbe }} + readinessProbe: {{ toYaml . | nindent 10 }} + {{- end }} + {{- with $root.Values.startupProbe }} + startupProbe: {{ toYaml . | nindent 10 }} + {{- end }} + {{- with $root.Values.lifecycle }} + lifecycle: {{ toYaml . | nindent 10 }} + {{- end }} volumeMounts: - name: gremlin-state mountPath: /var/lib/gremlin @@ -245,6 +278,9 @@ spec: subPath: {{ $gpu.openclIcd.filename }} readOnly: true {{- end }} + {{- with $root.Values.extraVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} volumes: - name: cgroup-root hostPath: @@ -293,6 +329,9 @@ spec: configMap: name: {{ include "gremlin.fullname" $root }}-opencl-icd {{- end }} + {{- with $root.Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- if $root.Values.gremlin.priorityClassName }} priorityClassName: {{ $root.Values.gremlin.priorityClassName }} {{- end }} diff --git a/gremlin/templates/_validation.tpl b/gremlin/templates/_validation.tpl index 48a93ec..69425db 100644 --- a/gremlin/templates/_validation.tpl +++ b/gremlin/templates/_validation.tpl @@ -84,3 +84,103 @@ stray space would silently become something other than what was written. {{- end -}} {{- end -}} {{- end -}} + +{{/* +Reserved volume names the Gremlin DaemonSet itself manages, one per line (flush left -- no leading +whitespace, no comment lines; splitList "\n" turns a leading/trailing blank into an empty entry +that never matches a real name, but keep entries flush left anyway since indentation would +otherwise become part of the name). Includes the container-driver socket volumes, derived from +.Values.containerDrivers.*.name rather than hardcoded, so a renamed driver stays covered. Callers +turn this into a list with splitList "\n" (include "gremlin.reservedNames.daemonsetVolumes" .). +Keeping this in one named template means there is exactly one place to edit when a new +chart-managed volume name appears. +*/}} +{{- define "gremlin.reservedNames.daemonsetVolumes" -}} +gremlin-state +gremlin-executions +gremlin-logs +cgroup-root +seccomp-root +seccomp-profile +gremlin-cert +ssl-cert-file +gremlin-tls-identity +gremlin-opencl-icd +kfd +dri +opencl-vendors +{{- range $key, $val := .Values.containerDrivers }} +{{ $val.name }}-sock +{{- end }} +{{- end -}} + +{{/* +Reserved container names the Gremlin DaemonSet itself manages, one per line. See +gremlin.reservedNames.daemonsetVolumes for the calling convention and formatting rules. +*/}} +{{- define "gremlin.reservedNames.daemonsetContainers" -}} +seccomp-init +gremlin +{{- end -}} + +{{/* +Reserved volume names the Chao deployment itself manages, one per line. Deliberately a separate, +narrower list from the DaemonSet's -- Chao renders only gremlin-cert (unconditional), +ssl-cert-file (when ssl.certFile is set), and chao-tls-identity (when chao.tls.identity is +configured); reusing the DaemonSet's list here would reject chao.extraVolumes/extraVolumeMounts +entries that don't actually collide with anything Chao renders. +*/}} +{{- define "gremlin.reservedNames.chaoVolumes" -}} +gremlin-cert +ssl-cert-file +chao-tls-identity +{{- end -}} + +{{/* +Reserved container names the Chao deployment itself manages, one per line. Chao's pod has a single +container (chao) and no chart-managed init container, unlike the DaemonSet's seccomp-init. +*/}} +{{- define "gremlin.reservedNames.chaoContainers" -}} +chao +{{- end -}} + +{{/* +Generic reserved-name collision check. Takes dict "entries" "reserved" "valuePath" + "kind" , and fails on the first entry whose .name is in the reserved list. An +entry with no name field does not match and is left to the Kubernetes API to reject. +*/}} +{{- define "gremlin.validateReservedNames.check" -}} +{{- range $entry := .entries -}} +{{- if $entry.name -}} +{{- if has $entry.name $.reserved -}} +{{- fail (printf "%s: %q collides with a %s name the gremlin chart manages. Rename it." $.valuePath $entry.name $.kind) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Reserved-name collision checks for the Gremlin DaemonSet's user-supplied initContainers, +extraVolumes, and extraVolumeMounts. Calls fail directly rather than contributing to +gremlin.validateValues's aggregate message, so it also fires when a single template +(daemonset.yaml) is rendered on its own. +*/}} +{{- define "gremlin.validateReservedNames.daemonset" -}} +{{- $volumes := splitList "\n" (include "gremlin.reservedNames.daemonsetVolumes" .) -}} +{{- $containers := splitList "\n" (include "gremlin.reservedNames.daemonsetContainers" .) -}} +{{- include "gremlin.validateReservedNames.check" (dict "entries" .Values.initContainers "reserved" $containers "valuePath" "initContainers" "kind" "container") -}} +{{- include "gremlin.validateReservedNames.check" (dict "entries" .Values.extraVolumes "reserved" $volumes "valuePath" "extraVolumes" "kind" "volume") -}} +{{- include "gremlin.validateReservedNames.check" (dict "entries" .Values.extraVolumeMounts "reserved" $volumes "valuePath" "extraVolumeMounts" "kind" "volume") -}} +{{- end -}} + +{{/* +Reserved-name collision checks for the Chao deployment's user-supplied initContainers, +extraVolumes, and extraVolumeMounts. See gremlin.validateReservedNames.daemonset. +*/}} +{{- define "gremlin.validateReservedNames.chao" -}} +{{- $volumes := splitList "\n" (include "gremlin.reservedNames.chaoVolumes" .) -}} +{{- $containers := splitList "\n" (include "gremlin.reservedNames.chaoContainers" .) -}} +{{- include "gremlin.validateReservedNames.check" (dict "entries" .Values.chao.initContainers "reserved" $containers "valuePath" "chao.initContainers" "kind" "container") -}} +{{- include "gremlin.validateReservedNames.check" (dict "entries" .Values.chao.extraVolumes "reserved" $volumes "valuePath" "chao.extraVolumes" "kind" "volume") -}} +{{- include "gremlin.validateReservedNames.check" (dict "entries" .Values.chao.extraVolumeMounts "reserved" $volumes "valuePath" "chao.extraVolumeMounts" "kind" "volume") -}} +{{- end -}} diff --git a/gremlin/templates/chao-deployment.yaml b/gremlin/templates/chao-deployment.yaml index 65a561a..8323a00 100644 --- a/gremlin/templates/chao-deployment.yaml +++ b/gremlin/templates/chao-deployment.yaml @@ -1,5 +1,6 @@ {{ if .Values.chao.create }} {{- include "chaoNamespacesValidate" . -}} +{{- include "gremlin.validateReservedNames.chao" . -}} apiVersion: apps/v1 kind: Deployment metadata: @@ -53,6 +54,21 @@ spec: imagePullSecrets: - name: {{ .Values.chaoimage.pullSecret }} {{- end }} + {{- if not (kindIs "invalid" .Values.chao.terminationGracePeriodSeconds) }} + terminationGracePeriodSeconds: {{ .Values.chao.terminationGracePeriodSeconds | toJson }} + {{- end }} + {{- with .Values.chao.dnsConfig }} + dnsConfig: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.chao.hostAliases }} + hostAliases: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.chao.podSecurityContext }} + securityContext: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.chao.initContainers }} + initContainers: {{ toYaml . | nindent 8 }} + {{- end }} containers: - image: {{ .Values.chaoimage.repository }}:{{ .Values.chaoimage.tag }} {{- with (default .Values.resources .Values.chao.resources) }} @@ -106,6 +122,21 @@ spec: {{- with .Values.chao.extraEnv }} {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.chao.envFrom }} + envFrom: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.chao.livenessProbe }} + livenessProbe: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.chao.readinessProbe }} + readinessProbe: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.chao.startupProbe }} + startupProbe: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.chao.lifecycle }} + lifecycle: {{ toYaml . | nindent 12 }} + {{- end }} args: - "-api_url" - "{{ include "gremlinServiceUrl" . }}/kubernetes" @@ -145,7 +176,7 @@ spec: {{- end }} imagePullPolicy: {{ .Values.chaoimage.pullPolicy }} name: chao -{{- if (or ((eq (include "gremlin.secretType" .) "certificate")) .Values.ssl.certFile (include "chaoTlsIdentityVolumeMounts" .)) }} +{{- if (or ((eq (include "gremlin.secretType" .) "certificate")) .Values.ssl.certFile (include "chaoTlsIdentityVolumeMounts" .) .Values.chao.extraVolumeMounts) }} volumeMounts: {{- end }} {{- if (eq (include "gremlin.secretType" .) "certificate") }} @@ -160,6 +191,9 @@ spec: {{- end }} {{- if include "chaoTlsIdentityVolumeMounts" . }} {{- include "chaoTlsIdentityVolumeMounts" . | nindent 10 }} +{{- end }} +{{- with .Values.chao.extraVolumeMounts }} +{{- toYaml . | nindent 10 }} {{- end }} volumes: - name: gremlin-cert @@ -173,6 +207,9 @@ spec: {{- if include "chaoTlsIdentityVolumes" . }} {{- include "chaoTlsIdentityVolumes" . | nindent 6 }} {{- end }} +{{- with .Values.chao.extraVolumes }} +{{- toYaml . | nindent 6 }} +{{- end }} {{- if .Values.chao.priorityClassName }} priorityClassName: {{ .Values.chao.priorityClassName }} {{- end }} diff --git a/gremlin/templates/daemonset.yaml b/gremlin/templates/daemonset.yaml index c1def39..404c0a0 100644 --- a/gremlin/templates/daemonset.yaml +++ b/gremlin/templates/daemonset.yaml @@ -8,6 +8,7 @@ template (see _daemonset.tpl), which knows nothing about GPUs or node mixes. that vendor's nodes and carrying that vendor's GPU config, plus `-gpu-none` for every node that belongs to none of those vendors. */ -}} +{{- include "gremlin.validateReservedNames.daemonset" . -}} {{- $fullname := include "gremlin.fullname" $ -}} {{- if .Values.gremlin.gpu.enabled -}} {{- $vendors := default (list) .Values.gremlin.gpu.vendors -}} diff --git a/gremlin/tests/dnsconfig_test.yaml b/gremlin/tests/dnsconfig_test.yaml new file mode 100644 index 0000000..0eb6765 --- /dev/null +++ b/gremlin/tests/dnsconfig_test.yaml @@ -0,0 +1,56 @@ +suite: dnsConfig +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should render a user-supplied dnsConfig on the gremlin DaemonSet + set: + dnsConfig: + nameservers: + - 10.0.0.10 + searches: + - svc.cluster.local + asserts: + - equal: + path: spec.template.spec.dnsConfig + value: + nameservers: + - 10.0.0.10 + searches: + - svc.cluster.local + template: daemonset.yaml + + - it: should not render a dnsConfig field on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.dnsConfig + template: daemonset.yaml + + - it: should render a user-supplied dnsConfig on the chao Deployment + set: + chao.dnsConfig: + nameservers: + - 10.0.0.10 + searches: + - svc.cluster.local + asserts: + - equal: + path: spec.template.spec.dnsConfig + value: + nameservers: + - 10.0.0.10 + searches: + - svc.cluster.local + template: chao-deployment.yaml + + - it: should not render a dnsConfig field on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.dnsConfig + template: chao-deployment.yaml diff --git a/gremlin/tests/envfrom_test.yaml b/gremlin/tests/envfrom_test.yaml new file mode 100644 index 0000000..c15cf4e --- /dev/null +++ b/gremlin/tests/envfrom_test.yaml @@ -0,0 +1,56 @@ +suite: envFrom +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should render user-supplied envFrom sources on the gremlin DaemonSet + set: + envFrom: + - configMapRef: + name: gremlin-extra-config + - secretRef: + name: gremlin-extra-secret + asserts: + - equal: + path: spec.template.spec.containers[0].envFrom + value: + - configMapRef: + name: gremlin-extra-config + - secretRef: + name: gremlin-extra-secret + template: daemonset.yaml + + - it: should not render an envFrom field on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.containers[0].envFrom + template: daemonset.yaml + + - it: should render user-supplied envFrom sources on the chao Deployment + set: + chao.envFrom: + - configMapRef: + name: chao-extra-config + - secretRef: + name: chao-extra-secret + asserts: + - equal: + path: spec.template.spec.containers[0].envFrom + value: + - configMapRef: + name: chao-extra-config + - secretRef: + name: chao-extra-secret + template: chao-deployment.yaml + + - it: should not render an envFrom field on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.containers[0].envFrom + template: chao-deployment.yaml diff --git a/gremlin/tests/extra_env_exempt_test.yaml b/gremlin/tests/extra_env_exempt_test.yaml new file mode 100644 index 0000000..913b970 --- /dev/null +++ b/gremlin/tests/extra_env_exempt_test.yaml @@ -0,0 +1,40 @@ +suite: extraEnv is exempt from the reserved-name collision check +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should still render successfully when gremlin.extraEnv shadows a chart-managed env var name + set: + gremlin.extraEnv: + - name: GREMLIN_TEAM_ID + value: overridden-team-id + asserts: + - notFailedTemplate: {} + template: daemonset.yaml + - contains: + path: spec.template.spec.containers[0].env + content: + name: GREMLIN_TEAM_ID + value: overridden-team-id + template: daemonset.yaml + + - it: should still render successfully when chao.extraEnv shadows a chart-managed env var name + set: + chao.extraEnv: + - name: GREMLIN_CLUSTER_ID + value: overridden-cluster-id + asserts: + - notFailedTemplate: {} + template: chao-deployment.yaml + - contains: + path: spec.template.spec.containers[0].env + content: + name: GREMLIN_CLUSTER_ID + value: overridden-cluster-id + template: chao-deployment.yaml diff --git a/gremlin/tests/extra_volumes_reject_test.yaml b/gremlin/tests/extra_volumes_reject_test.yaml new file mode 100644 index 0000000..6c8ddbc --- /dev/null +++ b/gremlin/tests/extra_volumes_reject_test.yaml @@ -0,0 +1,114 @@ +suite: extraVolumes / extraVolumeMounts reserved-name collision +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should fail the gremlin DaemonSet render when extraVolumes collides with a reserved volume name + set: + extraVolumes: + - name: gremlin-state + emptyDir: {} + asserts: + - failedTemplate: + errorMessage: 'extraVolumes: "gremlin-state" collides with a volume name the gremlin chart manages. Rename it.' + template: daemonset.yaml + + - it: should fail the gremlin DaemonSet render when extraVolumeMounts collides with a reserved volume name + set: + extraVolumeMounts: + - name: cgroup-root + mountPath: /somewhere + asserts: + - failedTemplate: + errorMessage: 'extraVolumeMounts: "cgroup-root" collides with a volume name the gremlin chart manages. Rename it.' + template: daemonset.yaml + + - it: should fail the gremlin DaemonSet render when extraVolumes collides with a renamed container-driver socket volume + set: + containerDrivers: + docker-linux: + name: custom + gremlin: + container: + driver: docker-linux + extraVolumes: + - name: custom-sock + hostPath: + path: /tmp + asserts: + - failedTemplate: + errorMessage: 'extraVolumes: "custom-sock" collides with a volume name the gremlin chart manages. Rename it.' + template: daemonset.yaml + + - it: should not fail the gremlin DaemonSet render when extraVolumes/extraVolumeMounts do not collide + set: + extraVolumes: + - name: debug-logs + hostPath: + path: /var/log/debug + extraVolumeMounts: + - name: debug-logs + mountPath: /var/log/debug + asserts: + - notFailedTemplate: {} + template: daemonset.yaml + + - it: should fail the chao Deployment render when extraVolumes collides with a reserved volume name + set: + chao.extraVolumes: + - name: gremlin-cert + emptyDir: {} + asserts: + - failedTemplate: + errorMessage: 'chao.extraVolumes: "gremlin-cert" collides with a volume name the gremlin chart manages. Rename it.' + template: chao-deployment.yaml + + - it: should fail the chao Deployment render when extraVolumeMounts collides with a reserved volume name + set: + chao.extraVolumeMounts: + - name: ssl-cert-file + mountPath: /somewhere + asserts: + - failedTemplate: + errorMessage: 'chao.extraVolumeMounts: "ssl-cert-file" collides with a volume name the gremlin chart manages. Rename it.' + template: chao-deployment.yaml + + - it: should not fail the chao Deployment render when extraVolumes/extraVolumeMounts do not collide + set: + chao.extraVolumes: + - name: debug-logs + hostPath: + path: /var/log/debug + chao.extraVolumeMounts: + - name: debug-logs + mountPath: /var/log/debug + asserts: + - notFailedTemplate: {} + template: chao-deployment.yaml + + - it: should not fail the chao Deployment render when extraVolumes uses a name only the gremlin DaemonSet reserves + set: + chao.extraVolumes: + - name: cgroup-root + hostPath: + path: /tmp + asserts: + - notFailedTemplate: {} + template: chao-deployment.yaml + + - it: should render nothing for chao when chao.create is false, even with a colliding extraVolumes name + set: + chao.create: false + chao.extraVolumes: + - name: gremlin-cert + emptyDir: {} + asserts: + - hasDocuments: + count: 0 + template: chao-deployment.yaml diff --git a/gremlin/tests/extra_volumes_test.yaml b/gremlin/tests/extra_volumes_test.yaml new file mode 100644 index 0000000..7152dd3 --- /dev/null +++ b/gremlin/tests/extra_volumes_test.yaml @@ -0,0 +1,100 @@ +suite: extraVolumes / extraVolumeMounts +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should append a user-supplied volume and mount on the gremlin DaemonSet + set: + extraVolumes: + - name: debug-logs + hostPath: + path: /var/log/debug + extraVolumeMounts: + - name: debug-logs + mountPath: /var/log/debug + readOnly: true + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: debug-logs + hostPath: + path: /var/log/debug + template: daemonset.yaml + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: debug-logs + mountPath: /var/log/debug + readOnly: true + template: daemonset.yaml + + - it: should not render the extra volume or mount on the gremlin DaemonSet by default + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: debug-logs + template: daemonset.yaml + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: debug-logs + template: daemonset.yaml + + - it: should append a user-supplied volume and mount on the chao Deployment + set: + chao.extraVolumes: + - name: debug-logs + hostPath: + path: /var/log/debug + chao.extraVolumeMounts: + - name: debug-logs + mountPath: /var/log/debug + readOnly: true + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: debug-logs + hostPath: + path: /var/log/debug + template: chao-deployment.yaml + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: debug-logs + mountPath: /var/log/debug + readOnly: true + template: chao-deployment.yaml + + - it: should bring the volumeMounts key into existence on chao when no other volumeMounts gate condition holds + set: + gremlin.secret.managed: true + gremlin.secret.type: secret + gremlin.secret.teamID: test-team-id + gremlin.secret.teamSecret: test-team-secret + chao.extraVolumeMounts: + - name: debug-logs + mountPath: /var/log/debug + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: debug-logs + mountPath: /var/log/debug + template: chao-deployment.yaml + + - it: should not render the extra volume or mount on the chao Deployment by default + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: debug-logs + template: chao-deployment.yaml diff --git a/gremlin/tests/hostaliases_test.yaml b/gremlin/tests/hostaliases_test.yaml new file mode 100644 index 0000000..77ff12e --- /dev/null +++ b/gremlin/tests/hostaliases_test.yaml @@ -0,0 +1,52 @@ +suite: hostAliases +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should render user-supplied hostAliases on the gremlin DaemonSet + set: + hostAliases: + - ip: "10.0.0.5" + hostnames: + - internal.gremlin.example + asserts: + - equal: + path: spec.template.spec.hostAliases + value: + - ip: "10.0.0.5" + hostnames: + - internal.gremlin.example + template: daemonset.yaml + + - it: should not render a hostAliases field on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.hostAliases + template: daemonset.yaml + + - it: should render user-supplied hostAliases on the chao Deployment + set: + chao.hostAliases: + - ip: "10.0.0.5" + hostnames: + - internal.gremlin.example + asserts: + - equal: + path: spec.template.spec.hostAliases + value: + - ip: "10.0.0.5" + hostnames: + - internal.gremlin.example + template: chao-deployment.yaml + + - it: should not render a hostAliases field on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.hostAliases + template: chao-deployment.yaml diff --git a/gremlin/tests/init_containers_reject_test.yaml b/gremlin/tests/init_containers_reject_test.yaml new file mode 100644 index 0000000..ecb9739 --- /dev/null +++ b/gremlin/tests/init_containers_reject_test.yaml @@ -0,0 +1,70 @@ +suite: initContainers reserved-name collision +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should fail the gremlin DaemonSet render when initContainers collides with a reserved container name + set: + initContainers: + - name: seccomp-init + image: busybox:1.36 + asserts: + - failedTemplate: + errorMessage: 'initContainers: "seccomp-init" collides with a container name the gremlin chart manages. Rename it.' + template: daemonset.yaml + + - it: should still fail exactly once and render the fan-out when GPU is enabled and initContainers collides + set: + gremlin.gpu.enabled: true + initContainers: + - name: gremlin + image: busybox:1.36 + asserts: + - failedTemplate: + errorMessage: 'initContainers: "gremlin" collides with a container name the gremlin chart manages. Rename it.' + template: daemonset.yaml + + - it: should not fail the gremlin DaemonSet render when initContainers does not collide + set: + initContainers: + - name: wait-for-node-ready + image: busybox:1.36 + asserts: + - notFailedTemplate: {} + template: daemonset.yaml + + - it: should fail the chao Deployment render when initContainers collides with a reserved container name + set: + chao.initContainers: + - name: chao + image: busybox:1.36 + asserts: + - failedTemplate: + errorMessage: 'chao.initContainers: "chao" collides with a container name the gremlin chart manages. Rename it.' + template: chao-deployment.yaml + + - it: should not fail the chao Deployment render when initContainers does not collide + set: + chao.initContainers: + - name: debug-network-check + image: busybox:1.36 + asserts: + - notFailedTemplate: {} + template: chao-deployment.yaml + + - it: should render nothing for chao when chao.create is false, even with a colliding initContainers name + set: + chao.create: false + chao.initContainers: + - name: chao + image: busybox:1.36 + asserts: + - hasDocuments: + count: 0 + template: chao-deployment.yaml diff --git a/gremlin/tests/init_containers_test.yaml b/gremlin/tests/init_containers_test.yaml new file mode 100644 index 0000000..c85d9d2 --- /dev/null +++ b/gremlin/tests/init_containers_test.yaml @@ -0,0 +1,70 @@ +suite: user-supplied initContainers +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should append a user-supplied initContainer on the gremlin DaemonSet when seccomp is off + set: + initContainers: + - name: wait-for-node-ready + image: busybox:1.36 + command: ["sh", "-c", "until [ -f /var/run/node-ready ]; do sleep 1; done"] + asserts: + - equal: + path: spec.template.spec.initContainers[0] + value: + name: wait-for-node-ready + image: busybox:1.36 + command: ["sh", "-c", "until [ -f /var/run/node-ready ]; do sleep 1; done"] + template: daemonset.yaml + + - it: should order a user-supplied initContainer after seccomp-init on the gremlin DaemonSet + set: + gremlin.podSecurity.seccomp.enabled: true + gremlin.podSecurity.seccomp.profile: localhost/gremlin + initContainers: + - name: wait-for-node-ready + image: busybox:1.36 + command: ["sh", "-c", "until [ -f /var/run/node-ready ]; do sleep 1; done"] + asserts: + - equal: + path: spec.template.spec.initContainers[0].name + value: seccomp-init + template: daemonset.yaml + - equal: + path: spec.template.spec.initContainers[1].name + value: wait-for-node-ready + template: daemonset.yaml + + - it: should not render initContainers on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.initContainers + template: daemonset.yaml + + - it: should append a user-supplied initContainer on the chao Deployment + set: + chao.initContainers: + - name: debug-network-check + image: busybox:1.36 + command: ["sh", "-c", "nslookup kubernetes.default"] + asserts: + - equal: + path: spec.template.spec.initContainers[0] + value: + name: debug-network-check + image: busybox:1.36 + command: ["sh", "-c", "nslookup kubernetes.default"] + template: chao-deployment.yaml + + - it: should not render initContainers on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.initContainers + template: chao-deployment.yaml diff --git a/gremlin/tests/lifecycle_test.yaml b/gremlin/tests/lifecycle_test.yaml new file mode 100644 index 0000000..d5aead5 --- /dev/null +++ b/gremlin/tests/lifecycle_test.yaml @@ -0,0 +1,52 @@ +suite: lifecycle hooks +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should render a user-supplied lifecycle on the gremlin DaemonSet + set: + lifecycle: + preStop: + exec: + command: ["sh", "-c", "sleep 5"] + asserts: + - equal: + path: spec.template.spec.containers[0].lifecycle + value: + preStop: + exec: + command: ["sh", "-c", "sleep 5"] + template: daemonset.yaml + + - it: should not render a lifecycle field on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.containers[0].lifecycle + template: daemonset.yaml + + - it: should render a user-supplied lifecycle on the chao Deployment + set: + chao.lifecycle: + preStop: + exec: + command: ["sh", "-c", "sleep 5"] + asserts: + - equal: + path: spec.template.spec.containers[0].lifecycle + value: + preStop: + exec: + command: ["sh", "-c", "sleep 5"] + template: chao-deployment.yaml + + - it: should not render a lifecycle field on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.containers[0].lifecycle + template: chao-deployment.yaml diff --git a/gremlin/tests/pod_security_context_test.yaml b/gremlin/tests/pod_security_context_test.yaml new file mode 100644 index 0000000..ba640e3 --- /dev/null +++ b/gremlin/tests/pod_security_context_test.yaml @@ -0,0 +1,62 @@ +suite: pod-level securityContext +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should render a user-supplied pod-level securityContext on the gremlin DaemonSet + set: + podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 + asserts: + - equal: + path: spec.template.spec.securityContext + value: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 + template: daemonset.yaml + # container-level securityContext is untouched by the pod-level value + - equal: + path: spec.template.spec.containers[0].securityContext.privileged + value: false + template: daemonset.yaml + + - it: should not render a pod-level securityContext on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.securityContext + template: daemonset.yaml + + - it: should render a user-supplied pod-level securityContext on the chao Deployment + set: + chao.podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 + asserts: + - equal: + path: spec.template.spec.securityContext + value: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 + template: chao-deployment.yaml + # container-level securityContext is untouched by the pod-level value + - equal: + path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem + value: true + template: chao-deployment.yaml + + - it: should not render a pod-level securityContext on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.securityContext + template: chao-deployment.yaml diff --git a/gremlin/tests/probes_test.yaml b/gremlin/tests/probes_test.yaml new file mode 100644 index 0000000..b475f21 --- /dev/null +++ b/gremlin/tests/probes_test.yaml @@ -0,0 +1,140 @@ +suite: probes (liveness/readiness/startup) +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should render a user-supplied livenessProbe on the gremlin DaemonSet + set: + livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 5 + asserts: + - equal: + path: spec.template.spec.containers[0].livenessProbe + value: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 5 + template: daemonset.yaml + + - it: should render a user-supplied readinessProbe on the gremlin DaemonSet + set: + readinessProbe: + httpGet: + path: /ready + port: 8080 + periodSeconds: 5 + asserts: + - equal: + path: spec.template.spec.containers[0].readinessProbe + value: + httpGet: + path: /ready + port: 8080 + periodSeconds: 5 + template: daemonset.yaml + + - it: should render a user-supplied startupProbe on the gremlin DaemonSet + set: + startupProbe: + exec: + command: ["cat", "/tmp/gremlin-ready"] + failureThreshold: 30 + periodSeconds: 10 + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe + value: + exec: + command: ["cat", "/tmp/gremlin-ready"] + failureThreshold: 30 + periodSeconds: 10 + template: daemonset.yaml + + - it: should not render any probe fields on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.containers[0].livenessProbe + template: daemonset.yaml + - notExists: + path: spec.template.spec.containers[0].readinessProbe + template: daemonset.yaml + - notExists: + path: spec.template.spec.containers[0].startupProbe + template: daemonset.yaml + + - it: should render a user-supplied livenessProbe on the chao Deployment + set: + chao.livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 5 + asserts: + - equal: + path: spec.template.spec.containers[0].livenessProbe + value: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 5 + template: chao-deployment.yaml + + - it: should render a user-supplied readinessProbe on the chao Deployment + set: + chao.readinessProbe: + httpGet: + path: /ready + port: 8080 + periodSeconds: 5 + asserts: + - equal: + path: spec.template.spec.containers[0].readinessProbe + value: + httpGet: + path: /ready + port: 8080 + periodSeconds: 5 + template: chao-deployment.yaml + + - it: should render a user-supplied startupProbe on the chao Deployment + set: + chao.startupProbe: + exec: + command: ["cat", "/tmp/chao-ready"] + failureThreshold: 30 + periodSeconds: 10 + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe + value: + exec: + command: ["cat", "/tmp/chao-ready"] + failureThreshold: 30 + periodSeconds: 10 + template: chao-deployment.yaml + + - it: should not render any probe fields on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.containers[0].livenessProbe + template: chao-deployment.yaml + - notExists: + path: spec.template.spec.containers[0].readinessProbe + template: chao-deployment.yaml + - notExists: + path: spec.template.spec.containers[0].startupProbe + template: chao-deployment.yaml diff --git a/gremlin/tests/termination_grace_period_test.yaml b/gremlin/tests/termination_grace_period_test.yaml new file mode 100644 index 0000000..7d1d72c --- /dev/null +++ b/gremlin/tests/termination_grace_period_test.yaml @@ -0,0 +1,77 @@ +suite: terminationGracePeriodSeconds +templates: + - daemonset.yaml + - chao-deployment.yaml +release: + name: my-release + namespace: my-namespace + revision: 1 + upgrade: true + +tests: + - it: should render a user-supplied terminationGracePeriodSeconds on the gremlin DaemonSet + set: + terminationGracePeriodSeconds: 45 + asserts: + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 45 + template: daemonset.yaml + + - it: should render terminationGracePeriodSeconds of 0 on the gremlin DaemonSet without being dropped as falsy + set: + terminationGracePeriodSeconds: 0 + asserts: + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 0 + template: daemonset.yaml + + - it: should not render terminationGracePeriodSeconds on the gremlin DaemonSet by default + asserts: + - notExists: + path: spec.template.spec.terminationGracePeriodSeconds + template: daemonset.yaml + + - it: should render a non-numeric terminationGracePeriodSeconds on the gremlin DaemonSet as its literal value, not silently coerce it to 0 + set: + terminationGracePeriodSeconds: not-a-number + asserts: + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: not-a-number + template: daemonset.yaml + + - it: should not let a multiline terminationGracePeriodSeconds string inject a sibling pod-spec field on the gremlin DaemonSet + set: + terminationGracePeriodSeconds: |- + 45 + hostIPC: true + asserts: + - notExists: + path: spec.template.spec.hostIPC + template: daemonset.yaml + + - it: should render a user-supplied terminationGracePeriodSeconds on the chao Deployment + set: + chao.terminationGracePeriodSeconds: 45 + asserts: + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 45 + template: chao-deployment.yaml + + - it: should render terminationGracePeriodSeconds of 0 on the chao Deployment without being dropped as falsy + set: + chao.terminationGracePeriodSeconds: 0 + asserts: + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 0 + template: chao-deployment.yaml + + - it: should not render terminationGracePeriodSeconds on the chao Deployment by default + asserts: + - notExists: + path: spec.template.spec.terminationGracePeriodSeconds + template: chao-deployment.yaml diff --git a/gremlin/values.yaml b/gremlin/values.yaml index a8a1fe4..d7c9d37 100644 --- a/gremlin/values.yaml +++ b/gremlin/values.yaml @@ -23,6 +23,97 @@ tolerations: [] affinity: {} +# livenessProbe - +# A Kubernetes Probe for the Gremlin Agent container. Applies to the Gremlin DaemonSet only; +# the Chao deployment has its own chao.livenessProbe. Passed through to the rendered manifest +# as-is. Unset by default, which renders no probe. +livenessProbe: {} + +# readinessProbe - +# A Kubernetes Probe for the Gremlin Agent container. Applies to the Gremlin DaemonSet only; +# the Chao deployment has its own chao.readinessProbe. Passed through to the rendered manifest +# as-is. Unset by default, which renders no probe. +readinessProbe: {} + +# startupProbe - +# A Kubernetes Probe for the Gremlin Agent container. Applies to the Gremlin DaemonSet only; +# the Chao deployment has its own chao.startupProbe. Passed through to the rendered manifest +# as-is. Unset by default, which renders no probe. +startupProbe: {} + +# initContainers - +# Additional init containers for the Gremlin DaemonSet's pod spec. Applies to the Gremlin +# DaemonSet only; the Chao deployment has its own chao.initContainers. Appended after any +# chart-managed init container (e.g. seccomp-init). Passed through to the rendered manifest +# as-is. A container name colliding with a name the gremlin chart manages (e.g. seccomp-init, +# gremlin) fails the install. Unset by default, which renders no additional init containers. +# NOTE: when gremlin.podSecurity.podSecurityPolicy.create (or ...securityContextConstraints.create) +# is enabled, the chart's own PSP/SCC may reject volumes an init container mounts; see +# extraVolumes below. +initContainers: [] + +# extraVolumes - +# Additional volumes for the Gremlin DaemonSet's pod spec. Applies to the Gremlin DaemonSet +# only; the Chao deployment has its own chao.extraVolumes. Passed through to the rendered +# manifest as-is. A volume name colliding with a name the gremlin chart manages (e.g. +# gremlin-state, gremlin-cert) fails the install. Unset by default, which renders no additional +# volumes. +# NOTE: when gremlin.podSecurity.podSecurityPolicy.create (or ...securityContextConstraints.create) +# is enabled, a volume type or hostPath outside what gremlin.podSecurity.volumes / +# allowedHostPaths permits is rejected at admission, not by this chart. +extraVolumes: [] + +# extraVolumeMounts - +# Additional volume mounts for the Gremlin Agent container. Applies to the Gremlin DaemonSet +# only; the Chao deployment has its own chao.extraVolumeMounts. Passed through to the rendered +# manifest as-is. A volume name colliding with a name the gremlin chart manages (e.g. +# gremlin-state, gremlin-cert) fails the install. Unset by default, which renders no additional +# volume mounts. +extraVolumeMounts: [] + +# lifecycle - +# A Kubernetes Lifecycle object (preStop/postStart hooks) for the Gremlin Agent container. +# Applies to the Gremlin DaemonSet only; the Chao deployment has its own chao.lifecycle. Passed +# through to the rendered manifest as-is. Unset by default, which renders no lifecycle hooks. +lifecycle: {} + +# envFrom - +# Additional sources (ConfigMaps/Secrets) to populate the Gremlin Agent container's environment +# from. Applies to the Gremlin DaemonSet only; the Chao deployment has its own chao.envFrom. +# Passed through to the rendered manifest as-is. Unset by default, which renders no envFrom. +# NOTE: unlike extraEnv, envFrom does NOT override chart-managed environment variables -- +# Kubernetes gives a container's env: precedence over its envFrom: for any key set in both. +# Use extraEnv (which renders last in env:) to override values such as GREMLIN_SERVICE_URL. +envFrom: [] + +# terminationGracePeriodSeconds - +# The termination grace period, in seconds, for the Gremlin DaemonSet's pods. Applies to the +# Gremlin DaemonSet only; the Chao deployment has its own chao.terminationGracePeriodSeconds. +# Passed through to the rendered manifest as-is. Unset by default, which leaves Kubernetes' +# default (30 seconds) in effect. +terminationGracePeriodSeconds: + +# dnsConfig - +# A Kubernetes PodDNSConfig object for the Gremlin DaemonSet's pod spec. Applies to the Gremlin +# DaemonSet only; the Chao deployment has its own chao.dnsConfig. Passed through to the rendered +# manifest as-is. Unset by default, which renders no dnsConfig. +dnsConfig: {} + +# hostAliases - +# A list of Kubernetes HostAlias entries for the Gremlin DaemonSet's pod spec. Applies to the +# Gremlin DaemonSet only; the Chao deployment has its own chao.hostAliases. Passed through to +# the rendered manifest as-is. Unset by default, which renders no hostAliases. +# NOTE: has no effect while gremlin.hostNetwork is true (the default), since the kubelet does +# not manage /etc/hosts for host-network pods. +hostAliases: [] + +# podSecurityContext - +# A Kubernetes pod-level SecurityContext for the Gremlin DaemonSet's pod spec. Applies to the +# Gremlin DaemonSet only; the Chao deployment has its own chao.podSecurityContext. Renders +# alongside the existing container-level securityContext, which is unaffected. Passed through +# to the rendered manifest as-is. Unset by default, which renders no pod-level securityContext. +podSecurityContext: {} + gremlin: # gremlin.updateStrategy - @@ -535,6 +626,95 @@ chao: # Specify any arbitrary environment variables to pass to the Chao deployment. extraEnv: [] + # chao.livenessProbe - + # A Kubernetes Probe for the Chao deployment's container. Applies to the Chao deployment only; + # the Gremlin DaemonSet has its own livenessProbe. Passed through to the rendered manifest + # as-is. Unset by default, which renders no probe. + livenessProbe: {} + + # chao.readinessProbe - + # A Kubernetes Probe for the Chao deployment's container. Applies to the Chao deployment only; + # the Gremlin DaemonSet has its own readinessProbe. Passed through to the rendered manifest + # as-is. Unset by default, which renders no probe. + readinessProbe: {} + + # chao.startupProbe - + # A Kubernetes Probe for the Chao deployment's container. Applies to the Chao deployment only; + # the Gremlin DaemonSet has its own startupProbe. Passed through to the rendered manifest + # as-is. Unset by default, which renders no probe. + startupProbe: {} + + # chao.initContainers - + # Additional init containers for the Chao deployment's pod spec. Applies to the Chao + # deployment only; the Gremlin DaemonSet has its own initContainers. Passed through to the + # rendered manifest as-is. A container name colliding with a name the gremlin chart manages + # (e.g. gremlin, chao) fails the install. Unset by default, which renders no additional init + # containers. + # NOTE: when gremlin.podSecurity.podSecurityPolicy.create is enabled, the chart's own chao PSP + # may reject volumes an init container mounts; see chao.extraVolumes below. + initContainers: [] + + # chao.extraVolumes - + # Additional volumes for the Chao deployment's pod spec. Applies to the Chao deployment only; + # the Gremlin DaemonSet has its own extraVolumes. Passed through to the rendered manifest + # as-is. A volume name colliding with a name the gremlin chart manages (e.g. gremlin-cert, + # chao-tls-identity) fails the install. Unset by default, which renders no additional volumes. + # NOTE: when gremlin.podSecurity.podSecurityPolicy.create is enabled, the chart's own chao PSP + # only permits the "secret" volume type; any other type is rejected at admission, not by this + # chart. + extraVolumes: [] + + # chao.extraVolumeMounts - + # Additional volume mounts for the Chao deployment's container. Applies to the Chao deployment + # only; the Gremlin DaemonSet has its own extraVolumeMounts. Passed through to the rendered + # manifest as-is. A volume name colliding with a name the gremlin chart manages (e.g. + # gremlin-cert, chao-tls-identity) fails the install. Unset by default, which renders no + # additional volume mounts. + extraVolumeMounts: [] + + # chao.lifecycle - + # A Kubernetes Lifecycle object (preStop/postStart hooks) for the Chao deployment's container. + # Applies to the Chao deployment only; the Gremlin DaemonSet has its own lifecycle. Passed + # through to the rendered manifest as-is. Unset by default, which renders no lifecycle hooks. + lifecycle: {} + + # chao.envFrom - + # Additional sources (ConfigMaps/Secrets) to populate the Chao deployment's container + # environment from. Applies to the Chao deployment only; the Gremlin DaemonSet has its own + # envFrom. Passed through to the rendered manifest as-is. Unset by default, which renders no + # envFrom. + # NOTE: unlike extraEnv, envFrom does NOT override chart-managed environment variables -- + # Kubernetes gives a container's env: precedence over its envFrom: for any key set in both. + # Use extraEnv (which renders last in env:) to override chart-managed values. + envFrom: [] + + # chao.terminationGracePeriodSeconds - + # The termination grace period, in seconds, for the Chao deployment's pods. Applies to the + # Chao deployment only; the Gremlin DaemonSet has its own terminationGracePeriodSeconds. + # Passed through to the rendered manifest as-is. Unset by default, which leaves Kubernetes' + # default (30 seconds) in effect. + terminationGracePeriodSeconds: + + # chao.dnsConfig - + # A Kubernetes PodDNSConfig object for the Chao deployment's pod spec. Applies to the Chao + # deployment only; the Gremlin DaemonSet has its own dnsConfig. Passed through to the rendered + # manifest as-is. Unset by default, which renders no dnsConfig. + dnsConfig: {} + + # chao.hostAliases - + # A list of Kubernetes HostAlias entries for the Chao deployment's pod spec. Applies to the + # Chao deployment only; the Gremlin DaemonSet has its own hostAliases. Passed through to the + # rendered manifest as-is. Unset by default, which renders no hostAliases. + hostAliases: [] + + # chao.podSecurityContext - + # A Kubernetes pod-level SecurityContext for the Chao deployment's pod spec. Applies to the + # Chao deployment only; the Gremlin DaemonSet has its own podSecurityContext. Renders + # alongside the existing container-level securityContext, which is unaffected. Passed through + # to the rendered manifest as-is. Unset by default, which renders no pod-level + # securityContext. + podSecurityContext: {} + # chao.namespaces # list of namespaces for Gremlin to watch for attacking namespaces: []