fix(chart): own the Datadog version label on every workload Pod (#7876)

## Summary

Every chart-managed Pod now carries a chart-owned
`tags.datadoghq.com/version` label derived from the deployed image,
instead of a value each wrapper restates once per workload.

Covered Pod templates:
- relay Deployment (`templates/deployment.yaml`)
- pairing relay (`templates/pairing-relay.yaml`)
- storage-accounting CronJob
(`templates/storage-accounting-cronjob.yaml`)
- operator jobs, including the deletion drain
(`templates/_operator-jobs.tpl`)

**Source order:** `image.tag`, then `image.digest`, then
`Chart.AppVersion` (`buzz.imageVersionSource`). Tag-first is deliberate:
- The rendered value matches the `sha-<commit>` pins wrappers already
carry, so upgrading to this chart does not roll any Pods.
- An image promotion only has to write `image.tag` + `image.digest`. No
per-workload label edit is needed.

Exact runtime identity stays exact in two places. The image reference is
`repository@digest` when a digest is pinned.
`BUZZ_STORAGE_SNAPSHOT_CODE_SHA` (persisted as `code_sha`) is still
digest-first.

**Label safety:** `buzz.imageVersionLabel` maps any OCI tag or digest to
a valid label value.
- Valid values already in Datadog's normal form (lowercase, no `__`)
pass through byte for byte, so `sha-<hex>` and `1.2.3-rc.4` are
unchanged. Datadog lowercases tag values and collapses `__`, so any
other value is hashed rather than allowed to report the same version as
a different revision.
- A digest keeps 63 hex characters.
- Anything else is replaced by the first 63 hex characters of its
SHA-256.
- Exactly 63 lowercase hex characters is reserved for the hashed and
digest forms, so a rendered label cannot be fed back as a tag to make
two revisions collide.
- When both tag and digest are set, the label names the tag even if they
disagree; the digest still pins what runs.

**Precedence:** a `tags.datadoghq.com/version` supplied through any
workload's `podLabels` is ignored. Every other label, including
`tags.datadoghq.com/env` and `/service`, passes through unchanged.
Overriding instead of failing means a wrapper with a stale pin is
corrected by the upgrade itself. The chart bump and the wrapper cleanup
don't have to land together.

**What got simpler:** one image identity instead of N. Wrappers delete
their per-workload version pins. Image promotion tooling no longer needs
a "mirror the tag into a label path" feature. One shared helper
(`buzz.podLabelsWithVersion`) replaces four `podLabels` passthroughs.

Chart `0.1.10 → 0.1.11`, with an `artifacthub.io/changes` entry.
Documented in the chart README ("Datadog version label") and
`docs/deployment-identity.md`.

Note: a vendor-namespaced label now renders unconditionally in an OSS
chart. This is in tension with
[VISION_SOVEREIGN.md](../blob/main/VISION_SOVEREIGN.md). The label is
inert without the operator-supplied `tags.datadoghq.com/service`/`env`,
and the chart already ships vendor-specific defaults (e.g.
`sidecar.istio.io/inject`).

### Testing

Run on a Blox (Linux) workstation at tree `41634b7ca` (helm v3.16.4,
helm-unittest 0.8.2, the CI versions):
- `helm lint deploy/charts/buzz`: 0 failed
- `helm unittest deploy/charts/buzz`: 12 suites, **85/85 passed**

New `tests/version_label_test.yaml` checks the relay, pairing relay, and
deletion drain: tag wins over a stale `podLabels` pin, the label is
stamped with no `podLabels`, and digest-only images get a label-safe
value. `tests/storage_accounting_test.yaml` covers the same cases for
the CronJob, plus the `Chart.AppVersion` fallback.

Mutation checks:
- Reverting any one template to the plain `podLabels` passthrough fails
tests.
- Switching the source order to digest-first fails tests.
- Restoring the case-insensitive passthrough fails the three
Datadog-normalization tests (uppercase, `__`, uppercased 63-hex).

No Rust, desktop, web, or mobile sources changed.

## Linear tracking

Related work: [BUZZ-215](https://linear.app/squareup/issue/BUZZ-215).

---------

Signed-off-by: tornquist <tornquist@squareup.com>
Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
This commit is contained in:
Luke Tornquist
2026-10-08 15:12:00 -04:00
committed by GitHub
parent 7e8aac4403
commit 5a93e862ee
12 changed files with 893 additions and 17 deletions

View File

@@ -7,7 +7,7 @@ description: |
PostgreSQL and Redis. Configurable for single-node evaluation
(subcharts on) and HA production (external services, existingSecret).
type: application
version: 0.1.10
version: 0.1.11
appVersion: "0.1.0"
home: https://github.com/block/buzz
sources:
@@ -23,8 +23,8 @@ maintainers:
url: https://github.com/block
annotations:
artifacthub.io/changes: |
- kind: added
description: Optional typed deletion-drain operator CronJob using durable database leases.
- kind: changed
description: Chart-managed Pods derive tags.datadoghq.com/version from the deployed image identity instead of operator-supplied labels.
artifacthub.io/license: Apache-2.0
# Optional eval-only subcharts. Production deploys disable both and point

View File

@@ -460,6 +460,85 @@ volumes, and each init container must define an appropriate security context
and resources. Empty `relay.command` and `relay.args` arrays preserve the image
defaults; non-empty values override its entrypoint and arguments respectively.
## Storage accounting worker
`storageAccounting.enabled=true` adds a CronJob that runs
`buzz-admin storage-snapshot` against the relay's S3 bucket and writes a
durable snapshot row, keeping the expensive object walk off the relay Pods.
### Snapshot identity contract
Every snapshot row records the code that produced it in `code_sha`, taken from
the `BUZZ_STORAGE_SNAPSHOT_CODE_SHA` environment variable the chart derives
from the deployed image identity (`image.digest` when set, otherwise
`image.tag`, otherwise `Chart.AppVersion`). The value is never hashed or
sanitized.
## Datadog version label
Every Pod the chart renders — relay, pairing relay, storage accounting, and the
deletion drain operator job — carries a chart-owned
`tags.datadoghq.com/version` label derived from the deployed image:
`image.tag` when set, otherwise `image.digest`, otherwise `Chart.AppVersion`.
The tag is preferred because it is the readable build name (`sha-<commit>`)
dashboards already use; promotion tooling writes it together with the digest
that actually pins the image.
```yaml
relay:
podLabels:
tags.datadoghq.com/env: production
tags.datadoghq.com/service: buzz
# tags.datadoghq.com/version: NOT set here — the chart owns it.
```
Precedence is explicit: a `tags.datadoghq.com/version` supplied under any
workload's `podLabels` is ignored. Every other label — including
`tags.datadoghq.com/env` and `tags.datadoghq.com/service`, which describe the
deployment rather than the image — passes through unchanged. Remove any
wrapper-maintained version pins when upgrading; a pin equal to `image.tag`
renders identically, so the upgrade does not roll Pods for that label.
A Kubernetes label value is capped at 63 bytes, must begin and end with an
alphanumeric, and may otherwise contain only `[-._a-zA-Z0-9]` — a far narrower
grammar than an OCI tag. `image.tag` is deliberately left unconstrained, so the
label is derived through a total mapping rather than a check that could reject
a tag the chart used to accept:
| Revision | Label |
|---|---|
| `sha256:<64 hex>` digest | the hex without `sha256:`, first 63 characters |
| already a valid label value, lowercase, no `__`, and not exactly 63 lowercase hex characters | emitted byte for byte (e.g. `1.2.3-rc.4`, `sha-1a2b3c4`) |
| anything else | the first 63 hex characters of the revision's SHA-256 |
The passthrough row requires Datadog's normal form because Datadog lowercases
tag values and collapses `__`: passing `ReleaseA` and `releasea` through
unchanged would report one version for two revisions. Every emitted label is
therefore already normalized, so distinct labels stay distinct in Datadog.
When both `image.tag` and `image.digest` are set, the label names the tag —
even if the tag and digest disagree. The digest still pins what actually runs
(`repository@digest`), so keep the two in step when promoting.
Exactly 63 lowercase hex characters is a **reserved shape** — it is what the
first and third rows emit, so the passthrough row must not be able to emit it
too. A tag of that shape is hashed rather than preserved. Shorter hex tags and
ordinary 40-character git SHAs are unaffected.
Arbitrary OCI revisions outnumber 63-byte label values, so **no mapping onto
this grammar can be injective** and the chart does not claim one. What it does
claim is collision *resistance*: every case retains 252 bits of SHA-256, the
same margin the digest case has always relied on, and the reserved shape keeps
that margin across cases rather than only within one. Two earlier iterations
fell short of this — one kept a readable prefix with only 40 bits of hash (a
colliding tag pair was brute-forced in about a second), and one let a
passthrough tag reproduce a hashed label with no hash work at all, by copying a
rendered label into `image.tag`.
The image reference in the Pod spec and `BUZZ_STORAGE_SNAPSHOT_CODE_SHA` always
keep the exact revision; the label is the joinable telemetry key. See
`docs/deployment-identity.md`.
## Device pairing relay
The chart can run Buzz's stateless pairing WebSocket relay as an independent

View File

@@ -76,6 +76,94 @@ app.kubernetes.io/component: relay
{{- end -}}
{{- end -}}
{{/*
Datadog unified-service-tagging version for every chart-managed Pod (relay,
pairing relay, storage accounting, operator jobs). It names the deployed image:
image.tag when set — the readable build name operators and dashboards already
use, which promotion tooling writes together with image.digest — otherwise the
digest, otherwise Chart.AppVersion. The chart owns this label so a wrapper never
has to pin a second copy of the image identity that silently drifts; the exact
runtime identity stays in the image reference and in
BUZZ_STORAGE_SNAPSHOT_CODE_SHA ("buzz.imageRevision").
*/}}
{{- define "buzz.imageVersionSource" -}}
{{- if .Values.image.tag -}}
{{- .Values.image.tag -}}
{{- else if .Values.image.digest -}}
{{- .Values.image.digest -}}
{{- else -}}
{{- .Chart.AppVersion -}}
{{- end -}}
{{- end -}}
{{/*
Kubernetes-label-safe rendering of "buzz.imageVersionSource".
A label value is at most 63 bytes, must begin and end with an alphanumeric,
and may otherwise contain only [-._a-zA-Z0-9]. image.tag is an unconstrained
string, so the domain is larger than the codomain and no mapping can be
injective; what the chart provides is a total mapping that is collision
*resistant*, in three cases:
1. A "sha256:<64 hex>" digest drops its algorithm prefix and keeps 63 hex
characters — the behaviour this chart has always had for digests.
2. A revision that is already a valid label value *and* already in Datadog's
normal form — no uppercase, no "__" — and is not of the reserved shape
below, is emitted byte for byte, so ordinary tags like 1.2.3-rc.4 and
sha-1a2b3c4 are preserved exactly.
3. Anything else — a leading "_", an uppercase letter, a "__" run, a byte
outside the label alphabet, or more than 63 bytes — is replaced by the
first 63 hex characters of its SHA-256, the same shape and the same 252
retained bits as case 1.
Case 2 is restricted to Datadog's normal form because the label's consumer is
Datadog, which lowercases tag values and collapses runs of "_". A passthrough
of "ReleaseA" would report the same version as "releasea", and "release__a"
the same as "release_a"; an uppercased 63-hex value would also slip past the
reserved-shape check below and then normalize onto a hashed or digest label.
Hashing everything not already in normal form means every value this helper
emits is a fixed point of Datadog's normalization, so distinct outputs stay
distinct where they are read.
Exactly 63 lowercase hex characters is the reserved shape: it is what cases 1
and 3 emit, so case 2 must not also be able to emit it. Without that exclusion
the two namespaces overlap and colliding two revisions costs no hash work at
all — render one, copy the label into image.tag, and the passthrough branch
echoes it back. Reserving the shape keeps every cross-case collision behind a
252-bit preimage, which is the same margin cases 1 and 3 already rely on. The
cost is that a tag which is itself 63 lowercase hex characters is hashed rather
than preserved; such a tag is not a form anything generates except this label.
Case 3 deliberately keeps no readable prefix. An earlier revision of this
helper kept a sanitized prefix plus 10 hex characters of SHA-256, and that
40-bit namespace was small enough to brute-force: the tags
"b"x52 + "-collision-22356" and "b"x52 + "-collision-914141" both rendered
"b"x52 + "-430be57931" (see tests/storage_accounting_test.yaml). Readability
is not worth a forgeable telemetry identity when the exact revision is always
available in the image reference itself.
*/}}
{{- define "buzz.imageVersionLabel" -}}
{{- $revision := include "buzz.imageVersionSource" . -}}
{{- if regexMatch "^sha256:[0-9a-f]{64}$" $revision -}}
{{- $revision | trimPrefix "sha256:" | trunc 63 -}}
{{- else if and (le (len $revision) 63) (regexMatch "^[a-z0-9]([-._a-z0-9]*[a-z0-9])?$" $revision) (not (contains "__" $revision)) (not (regexMatch "^[0-9a-f]{63}$" $revision)) -}}
{{- $revision -}}
{{- else -}}
{{- sha256sum $revision | trunc 63 -}}
{{- end -}}
{{- end -}}
{{/*
Pod-template labels for a chart-managed workload: the caller's podLabels with
the chart-owned Datadog version merged on top. Every other key, including
tags.datadoghq.com/env and tags.datadoghq.com/service, passes through.
Usage: include "buzz.podLabelsWithVersion" (dict "root" $ "labels" $podLabels)
*/}}
{{- define "buzz.podLabelsWithVersion" -}}
{{- $labels := merge (dict "tags.datadoghq.com/version" (include "buzz.imageVersionLabel" .root)) (.labels | default dict) -}}
{{- toYaml $labels -}}
{{- end -}}
{{/*
Name of the chart-managed Secret holding relay-identity material and any
chart-composed connection strings.

View File

@@ -30,9 +30,7 @@ spec:
labels:
{{- include "buzz.selectorLabels" $root | nindent 12 }}
app.kubernetes.io/component: deletion-drain
{{- with $job.podLabels }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- include "buzz.podLabelsWithVersion" (dict "root" $root "labels" $job.podLabels) | nindent 12 }}
annotations:
{{- toYaml $job.podAnnotations | nindent 12 }}
spec:

View File

@@ -21,9 +21,7 @@ spec:
metadata:
labels:
{{- include "buzz.relaySelectorLabels" . | nindent 8 }}
{{- with .Values.relay.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- include "buzz.podLabelsWithVersion" (dict "root" . "labels" .Values.relay.podLabels) | nindent 8 }}
annotations:
# Roll pods when the chart-managed Secret changes.
checksum/secret: {{ include (print $.Template.BasePath "/secret-chart.yaml") . | sha256sum }}

View File

@@ -16,9 +16,7 @@ spec:
metadata:
labels:
{{- include "buzz.pairingRelaySelectorLabels" . | nindent 8 }}
{{- with .Values.pairingRelay.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- include "buzz.podLabelsWithVersion" (dict "root" . "labels" .Values.pairingRelay.podLabels) | nindent 8 }}
{{- with .Values.pairingRelay.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}

View File

@@ -20,9 +20,7 @@ spec:
labels:
{{- include "buzz.selectorLabels" . | nindent 12 }}
app.kubernetes.io/component: storage-accounting
{{- with .Values.storageAccounting.podLabels }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- include "buzz.podLabelsWithVersion" (dict "root" . "labels" .Values.storageAccounting.podLabels) | nindent 12 }}
annotations:
{{- toYaml .Values.storageAccounting.podAnnotations | nindent 12 }}
spec:

View File

@@ -44,6 +44,7 @@ tests:
podLabels:
tags.datadoghq.com/env: production
tags.datadoghq.com/service: buzz-storage-accounting
# Stale operator pin: the chart owns this key and overrides it.
tags.datadoghq.com/version: test-sha
asserts:
- hasDocuments:
@@ -93,9 +94,11 @@ tests:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/env"]
value: production
template: templates/storage-accounting-cronjob.yaml
# Image identity wins over the operator-supplied pin; default image.tag
# falls back to Chart.AppVersion, the same value as the env var below.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: test-sha
value: 0.1.0
template: templates/storage-accounting-cronjob.yaml
- equal:
path: spec.jobTemplate.spec.template.spec.containers[0].args
@@ -165,3 +168,360 @@ tests:
path: metadata.name
value: storage-accounting-fullname-that-storage-accounting
template: templates/storage-accounting-cronjob.yaml
# ── Datadog version tag is chart-owned, derived from image identity ────────
# Regression: a wrapper chart pinned tags.datadoghq.com/version independently
# of image.tag/image.digest, so the storage-accounting Pod reported one
# version to Datadog while BUZZ_STORAGE_SNAPSHOT_CODE_SHA recorded another.
- it: overrides a stale operator-pinned Datadog version label with the image tag
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: 1.2.3-rc.4
storageAccounting:
enabled: true
podLabels:
tags.datadoghq.com/env: staging
tags.datadoghq.com/service: buzz-storage-accounting
tags.datadoghq.com/version: stale-operator-sha
team: platform
asserts:
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: 1.2.3-rc.4
template: templates/storage-accounting-cronjob.yaml
# The telemetry tag and the recorded snapshot identity cannot disagree.
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: 1.2.3-rc.4
template: templates/storage-accounting-cronjob.yaml
# Every other operator label still passes through.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/env"]
value: staging
template: templates/storage-accounting-cronjob.yaml
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/service"]
value: buzz-storage-accounting
template: templates/storage-accounting-cronjob.yaml
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["team"]
value: platform
template: templates/storage-accounting-cronjob.yaml
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["app.kubernetes.io/component"]
value: storage-accounting
template: templates/storage-accounting-cronjob.yaml
- it: stamps the version label with no operator podLabels at all
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: 2.0.0
storageAccounting:
enabled: true
asserts:
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: 2.0.0
template: templates/storage-accounting-cronjob.yaml
# Promotion writes image.tag and image.digest together; the tag is the
# readable build name Datadog already uses, the digest the runtime identity.
- it: names the image tag in the version label while the digest pins the image
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: sha-1234567
image.digest: sha256:1111111111111111111111111111111111111111111111111111111111111111
storageAccounting:
enabled: true
podLabels:
tags.datadoghq.com/version: stale-operator-sha
asserts:
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: sha-1234567
template: templates/storage-accounting-cronjob.yaml
# The snapshot row still records the exact digest that ran.
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: sha256:1111111111111111111111111111111111111111111111111111111111111111
template: templates/storage-accounting-cronjob.yaml
- it: renders a label-safe version from a digest when no tag is set
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.digest: sha256:1111111111111111111111111111111111111111111111111111111111111111
storageAccounting:
enabled: true
podLabels:
tags.datadoghq.com/version: stale-operator-sha
asserts:
# 63 chars, no "sha256:" prefix — a label value the API server accepts,
# still a unique prefix of the digest recorded in the env var below.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "111111111111111111111111111111111111111111111111111111111111111"
template: templates/storage-accounting-cronjob.yaml
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-z0-9A-Z]([-_.a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: sha256:1111111111111111111111111111111111111111111111111111111111111111
template: templates/storage-accounting-cronjob.yaml
# ── Label-safety of arbitrary OCI tags (PR #7876 review, P0) ───────────────
# image.tag is an unconstrained string in values.schema.json, so any tag the
# OCI grammar allows must still yield a valid Kubernetes label value. The
# chart replaces any revision that is not already label-safe with the first
# 63 hex characters of its SHA-256, the same shape it uses for digests.
- it: sanitizes a leading underscore that OCI allows but Kubernetes labels do not
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: "_foo"
storageAccounting:
enabled: true
asserts:
# Leading '_' is a valid OCI tag byte but an invalid first label byte.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "583da8894acbb7b121f9b85bc263859bd68c3a239f4934b62fc13f4f0beedc6"
template: templates/storage-accounting-cronjob.yaml
# The rendered label must satisfy the Kubernetes label-value grammar:
# <=63 bytes, alphanumeric first and last byte, [-._a-zA-Z0-9] inside.
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-zA-Z0-9]([-._a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
# The exact image revision still reaches the snapshot row unmodified.
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: "_foo"
template: templates/storage-accounting-cronjob.yaml
- it: keeps the label valid when truncation would land on mixed trailing delimiters
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-_.tail"
storageAccounting:
enabled: true
asserts:
# A one-pass '-'/'.'/'_' trim left a trailing '-' for a tag ending '-_.';
# a hex label has no delimiters to trim.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "e4fb46fc85bd57715b5a11055e17387d439f906e568445c24d27ba91fc4995f"
template: templates/storage-accounting-cronjob.yaml
# The rendered label must satisfy the Kubernetes label-value grammar:
# <=63 bytes, alphanumeric first and last byte, [-._a-zA-Z0-9] inside.
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-zA-Z0-9]([-._a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
# The exact image revision still reaches the snapshot row unmodified.
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-_.tail"
template: templates/storage-accounting-cronjob.yaml
- it: distinguishes the first of two >63-character tags sharing a 63-byte prefix
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-one"
storageAccounting:
enabled: true
asserts:
# Plain truncation collapses both tags to the same telemetry version.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "2aad1d5b65b546c6b4a5f4d46845078c7dfb91302d9824c884fff9f45f6398c"
template: templates/storage-accounting-cronjob.yaml
# The rendered label must satisfy the Kubernetes label-value grammar:
# <=63 bytes, alphanumeric first and last byte, [-._a-zA-Z0-9] inside.
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-zA-Z0-9]([-._a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
# The exact image revision still reaches the snapshot row unmodified.
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-one"
template: templates/storage-accounting-cronjob.yaml
- it: distinguishes the second of two >63-character tags sharing a 63-byte prefix
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-two"
storageAccounting:
enabled: true
asserts:
# Same 63-byte tag prefix as the previous case, different SHA-256.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "86dde532eb8217d9ab8648f38f12cd3568983910e0e668489a66c036734ae9a"
template: templates/storage-accounting-cronjob.yaml
# The rendered label must satisfy the Kubernetes label-value grammar:
# <=63 bytes, alphanumeric first and last byte, [-._a-zA-Z0-9] inside.
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-zA-Z0-9]([-._a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
# The exact image revision still reaches the snapshot row unmodified.
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-two"
template: templates/storage-accounting-cronjob.yaml
# ── Known 40-bit collision pair (PR #7876 second review, P0) ───────────────
# These two tags were found by brute force against the previous fallback,
# which kept only 10 hex characters of SHA-256: both rendered
# b*52-430be57931. They share a 40-bit SHA-256 prefix and diverge at the
# 11th hex character, so they pin the width of the retained hash.
- it: keeps the first tag of the known 40-bit collision pair distinct
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-collision-22356"
storageAccounting:
enabled: true
asserts:
# Shares its first 10 SHA-256 hex characters with the next case.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "430be579311332ea582db391704bd58601bcf0f3f5682d22bdabdac24a47169"
template: templates/storage-accounting-cronjob.yaml
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-zA-Z0-9]([-._a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-collision-22356"
template: templates/storage-accounting-cronjob.yaml
- it: keeps the second tag of the known 40-bit collision pair distinct
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-collision-914141"
storageAccounting:
enabled: true
asserts:
# Same 40-bit SHA-256 prefix as the previous case, different label.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "430be5793136081a42faa8d72f746af34f0b3bad1a5f65f22bac19e22bd71c5"
template: templates/storage-accounting-cronjob.yaml
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-zA-Z0-9]([-._a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-collision-914141"
template: templates/storage-accounting-cronjob.yaml
# ── Reserved hash shape is not reachable by a passthrough tag ──────────────
# The hashed and digest branches both emit exactly 63 lowercase hex
# characters. If a label-safe tag of that same shape were passed through, an
# operator could collide two revisions with no hash work at all, by copying a
# rendered label into image.tag. The label below is exactly what
# "b"x52 + "-collision-22356" renders, so the chart must hash it rather than
# echo it back.
- it: hashes a tag that has the reserved 63-hex shape instead of passing it through
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.accessKey: test
s3.secretKey: test
image.tag: "430be579311332ea582db391704bd58601bcf0f3f5682d22bdabdac24a47169"
storageAccounting:
enabled: true
asserts:
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "9f615034d2fe14c5266fe5ca3eb7c26c4179eae8dce01f506def01a8cc6a77e"
template: templates/storage-accounting-cronjob.yaml
# Must not echo the tag back: that is the label of a different revision.
- notEqual:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "430be579311332ea582db391704bd58601bcf0f3f5682d22bdabdac24a47169"
template: templates/storage-accounting-cronjob.yaml
- matchRegex:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
pattern: ^[a-zA-Z0-9]([-._a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$
template: templates/storage-accounting-cronjob.yaml
- contains:
path: spec.jobTemplate.spec.template.spec.containers[0].env
content:
name: BUZZ_STORAGE_SNAPSHOT_CODE_SHA
value: "430be579311332ea582db391704bd58601bcf0f3f5682d22bdabdac24a47169"
template: templates/storage-accounting-cronjob.yaml

View File

@@ -0,0 +1,313 @@
suite: chart-owned Datadog version label on every workload
# Regression: wrappers pinned tags.datadoghq.com/version beside image.tag on
# each workload, so every image promotion had to edit several copies of one
# identity and a missed copy reported the wrong version to Datadog. The chart
# now owns the label everywhere it renders a Pod (storage accounting is covered
# in storage_accounting_test.yaml).
templates:
- templates/deployment.yaml
- templates/secret-chart.yaml
- templates/pairing-relay.yaml
- templates/deletion-drain-cronjob.yaml
tests:
- it: derives the relay version label from image.tag over a stale pin
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.tag: sha-abcdef1
image.digest: sha256:2222222222222222222222222222222222222222222222222222222222222222
relay.podLabels:
tags.datadoghq.com/env: staging
tags.datadoghq.com/service: buzz-example
tags.datadoghq.com/version: sha-stale00
asserts:
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: sha-abcdef1
template: templates/deployment.yaml
# Deployment-describing labels still pass through.
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/env"]
value: staging
template: templates/deployment.yaml
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/service"]
value: buzz-example
template: templates/deployment.yaml
- it: stamps the relay version label with no podLabels configured
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.tag: sha-abcdef1
asserts:
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: sha-abcdef1
template: templates/deployment.yaml
- it: renders a label-safe relay version from a digest-only image
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.digest: sha256:2222222222222222222222222222222222222222222222222222222222222222
asserts:
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "222222222222222222222222222222222222222222222222222222222222222"
template: templates/deployment.yaml
- it: derives the pairing relay version label from image.tag over a stale pin
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
pairingRelay.enabled: true
pairingRelay.url: wss://pairing.buzz.xyz
image.tag: sha-abcdef1
image.digest: sha256:2222222222222222222222222222222222222222222222222222222222222222
pairingRelay.podLabels:
tags.datadoghq.com/env: staging
tags.datadoghq.com/service: buzz-example
tags.datadoghq.com/version: sha-stale00
asserts:
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: sha-abcdef1
template: templates/pairing-relay.yaml
documentIndex: 0
# Deployment-describing labels still pass through.
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/env"]
value: staging
template: templates/pairing-relay.yaml
documentIndex: 0
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/service"]
value: buzz-example
template: templates/pairing-relay.yaml
documentIndex: 0
- it: stamps the pairing relay version label with no podLabels configured
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
pairingRelay.enabled: true
pairingRelay.url: wss://pairing.buzz.xyz
image.tag: sha-abcdef1
asserts:
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: sha-abcdef1
template: templates/pairing-relay.yaml
documentIndex: 0
- it: renders a label-safe pairing relay version from a digest-only image
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
pairingRelay.enabled: true
pairingRelay.url: wss://pairing.buzz.xyz
image.digest: sha256:2222222222222222222222222222222222222222222222222222222222222222
asserts:
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "222222222222222222222222222222222222222222222222222222222222222"
template: templates/pairing-relay.yaml
documentIndex: 0
- it: derives the deletion drain version label from image.tag over a stale pin
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
operatorJobs.deletionDrain.enabled: true
image.tag: sha-abcdef1
image.digest: sha256:2222222222222222222222222222222222222222222222222222222222222222
operatorJobs.deletionDrain.podLabels:
tags.datadoghq.com/env: staging
tags.datadoghq.com/service: buzz-example
tags.datadoghq.com/version: sha-stale00
asserts:
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: sha-abcdef1
template: templates/deletion-drain-cronjob.yaml
# Deployment-describing labels still pass through.
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/env"]
value: staging
template: templates/deletion-drain-cronjob.yaml
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/service"]
value: buzz-example
template: templates/deletion-drain-cronjob.yaml
- it: stamps the deletion drain version label with no podLabels configured
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
operatorJobs.deletionDrain.enabled: true
image.tag: sha-abcdef1
asserts:
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: sha-abcdef1
template: templates/deletion-drain-cronjob.yaml
- it: renders a label-safe deletion drain version from a digest-only image
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
operatorJobs.deletionDrain.enabled: true
image.digest: sha256:2222222222222222222222222222222222222222222222222222222222222222
asserts:
- equal:
path: spec.jobTemplate.spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "222222222222222222222222222222222222222222222222222222222222222"
template: templates/deletion-drain-cronjob.yaml
# ── Datadog normalization (PR #7876 review, P0) ───────────────────────────
# Datadog lowercases tag values and collapses "__", so a passthrough of a
# non-normal value would merge two revisions into one reported version. Each
# pair below must render two labels that stay distinct after normalization.
- it: hashes a tag with uppercase so it cannot merge with its lowercase twin
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.tag: "ReleaseA"
asserts:
# Passed through, Datadog would read this as "releasea".
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "4592ae6466f715bbba35c9e1931fe5cdd548a4355947759b1fcf7f2b6f0e727"
template: templates/deployment.yaml
- notEqual:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "releasea"
template: templates/deployment.yaml
- it: passes through the lowercase twin of a hashed uppercase tag
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.tag: "releasea"
asserts:
# Already in Datadog normal form, so preserved byte for byte.
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "releasea"
template: templates/deployment.yaml
- it: hashes a tag containing a double underscore
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.tag: "release__a"
asserts:
# Passed through, Datadog would collapse this to "release_a".
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "ab213bb0d3409388c915a5d3ef384cd6d812237d4aa712081edfc1c1473daa1"
template: templates/deployment.yaml
- notEqual:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "release_a"
template: templates/deployment.yaml
- it: passes through the single-underscore twin of a hashed double-underscore tag
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.tag: "release_a"
asserts:
# Already in Datadog normal form, so preserved byte for byte.
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "release_a"
template: templates/deployment.yaml
- it: hashes an uppercased 63-hex tag instead of letting it alias the reserved shape
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: https://s3.example.com
s3.bucket: buzz-media-example
s3.accessKey: test
s3.secretKey: test
image.tag: "ABCDEF000000000000000000000000000000000000000000000000000000000"
asserts:
# Passed through, Datadog would lowercase this onto the reserved 63-hex shape that digest-derived labels use.
- equal:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "2435b36c0cdc7f75334db8b9151d18738e4358cd0fac9b260e98a84f0207b41"
template: templates/deployment.yaml
- notEqual:
path: spec.template.metadata.labels["tags.datadoghq.com/version"]
value: "abcdef000000000000000000000000000000000000000000000000000000000"
template: templates/deployment.yaml

View File

@@ -229,7 +229,10 @@
"failedJobsHistoryLimit": { "type": "integer", "minimum": 0 },
"relayMode": { "type": "string", "enum": ["inline", "external", "off"] },
"serviceAccountName": { "type": "string" },
"podLabels": { "type": "object" },
"podLabels": {
"type": "object",
"description": "Extra Pod labels. The chart owns tags.datadoghq.com/version and derives it from the deployed image identity, so a value supplied here for that one key is ignored."
},
"podAnnotations": { "type": "object" },
"resources": { "type": "object" }
}

View File

@@ -172,6 +172,7 @@ relay:
memory: "2Gi"
podAnnotations: {}
# tags.datadoghq.com/version is chart-owned; see README "Datadog version label".
podLabels: {}
nodeSelector: {}
tolerations: []
@@ -222,6 +223,7 @@ pairingRelay:
port: 5000
annotations: {}
podAnnotations: {}
# tags.datadoghq.com/version is chart-owned; see README "Datadog version label".
podLabels: {}
resources:
requests:
@@ -380,6 +382,9 @@ storageAccounting:
failedJobsHistoryLimit: 3
relayMode: external # external | off; inline is a legacy alias
serviceAccountName: "" # defaults to the main Buzz service account
# Extra Pod labels, e.g. Datadog unified service tagging. The chart owns
# `tags.datadoghq.com/version` on every workload (see README "Datadog version
# label"); a value supplied here for that one key is ignored.
podLabels: {}
podAnnotations:
sidecar.istio.io/inject: "false"
@@ -405,6 +410,7 @@ operatorJobs:
# Empty inherits the relay service account, and with it any cloud IAM
# binding on that account. Name a dedicated account to narrow the executor.
serviceAccountName: ""
# tags.datadoghq.com/version is chart-owned; see README "Datadog version label".
podLabels: {}
podAnnotations:
sidecar.istio.io/inject: "false"