Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"config:recommended",
":semanticCommits"
],
"enabledManagers": ["gomod", "dockerfile", "github-actions"],
"enabledManagers": ["gomod", "dockerfile", "github-actions", "custom.regex"],
"postUpdateOptions": ["gomodTidy", "gomodUpdateImportPaths"],
"labels": ["automated", "do-not-merge/hold"],
"automerge": false,
Expand All @@ -15,6 +15,15 @@
"enabled": true,
"labels": ["automated", "security"]
},
"customManagers": [
{
"customType": "regex",
"description": "Track the etcd image pinned in the extra/etcd EtcdCluster podTemplate. etcd-operator v0.4.5 bakes etcd 3.5.12 into its binary, and the chart overrides it with a hardcoded image string that the gomod/dockerfile managers cannot see. Without this manager the security-relevant pin (etcd 3.5.x releases are overwhelmingly security fixes) would silently age.",
"managerFilePatterns": ["/^packages/extra/etcd/templates/etcd-cluster\\.yaml$/"],
"matchStrings": ["image:\\s+(?<depName>quay\\.io/coreos/etcd):(?<currentValue>v[0-9]+\\.[0-9]+\\.[0-9]+)"],
"datasourceTemplate": "docker"
}
],
"packageRules": [
{
"description": "Bump indirect Go modules too. Transitive deps such as golang.org/x/crypto, golang.org/x/net and golang.org/x/sys carry OSV advisories that drive the OpenSSF Scorecard Vulnerabilities check to 0, but Renovate skips indirect gomod deps by default so they never get a PR. Grouped into one rolling PR to keep volume sane; security fixes are still split out by vulnerabilityAlerts above. Placed before the kubernetes rule on purpose: an indirect k8s.io/** dep matches both, and Renovate applies last-match-wins, so the later kubernetes rule keeps it in the kubernetes lockstep group.",
Expand Down
10 changes: 10 additions & 0 deletions packages/extra/etcd/templates/etcd-cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ spec:
spec:
containers:
- name: etcd
# Override the etcd image strategically merged into the operator's
# default pod spec. etcd-operator v0.4.5 hardcodes
# quay.io/coreos/etcd:v3.5.12 (DefaultEtcdImage), which the
# kube-apiserver rejects for consistent watches: it only enables the
# RequestWatchProgress storage feature on etcd >= 3.5.13 / >= 3.4.31.
# Kubernetes >= 1.31 enables ConsistentListFromCache (locked-to-true
# in 1.35), so on etcd 3.5.12 every consistent watch fails inside the
# stream with "the required storage feature RequestWatchProgress is
# disabled" (HTTP 500). Pinning a >= 3.5.13 patch release restores it.
image: quay.io/coreos/etcd:v3.5.31

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The etcd image version v3.5.31 does not exist. The etcd 3.5 release branch has not reached .31 (the latest release is around v3.5.17). This is likely a transposition typo of v3.5.13 (the minimum version required for RequestWatchProgress) or a mix-up with v3.4.31. Using a non-existent image tag will cause ErrImagePull / ImagePullBackOff and completely break the tenant etcd cluster. Please use a valid existing version, such as v3.5.13 or a newer stable patch release like v3.5.17.

        image: quay.io/coreos/etcd:v3.5.13

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed valid — this does not need changing. quay.io/coreos/etcd:v3.5.31 exists on quay.io as a multi-arch manifest list (amd64/arm64/ppc64le/s390x), published 2026-06-01, verified against the registry API. The "tag does not exist / latest is ~v3.5.17" comments predate the release.

The override also takes effect: the v1alpha1 EtcdCluster CRD exposes no spec.image/spec.version, so podTemplate is the only lever. etcd-operator v0.4.5 builds the etcd container with its hardcoded default and then strategic-merges podTemplate.spec over it (matched by container name etcd), so this image wins and the operator does not re-assert its default — the same mechanism already used here for the metrics port, probes, and resources.

ports:
- name: metrics
containerPort: 2381
Expand Down
41 changes: 41 additions & 0 deletions packages/extra/etcd/tests/etcd-cluster_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
suite: etcd cluster pins an etcd image new enough for consistent watches

# The exact patch version is intentionally NOT asserted: the image is a
# Renovate-tracked pin (.github/renovate.json) that bumps over time, so an
# exact-equality assertion would turn every etcd bump PR red in CI. The
# test encodes the durable contract instead - the etcd container image is
# overridden to a coreos/etcd release >= 3.5.13 (the floor at which
# kube-apiserver enables the RequestWatchProgress storage feature) and
# never falls back to the operator default v3.5.12.

release:
name: etcd
namespace: tenant-test

templates:
- templates/etcd-cluster.yaml

set:
_cluster: {}

tests:
- it: overrides the operator default etcd image with a >= 3.5.13 release
documentSelector:
path: kind
value: EtcdCluster
asserts:
- equal:
path: spec.podTemplate.spec.containers[0].name
value: etcd
- matchRegex:
path: spec.podTemplate.spec.containers[0].image
pattern: ^quay\.io/coreos/etcd:v(3\.5\.(1[3-9]|[2-9][0-9]|[1-9][0-9]{2,})|3\.([6-9]|[1-9][0-9])\.[0-9]+|[4-9][0-9]*\.[0-9]+\.[0-9]+)$

- it: never falls back to the operator default v3.5.12
documentSelector:
path: kind
value: EtcdCluster
asserts:
- notEqual:
path: spec.podTemplate.spec.containers[0].image
value: quay.io/coreos/etcd:v3.5.12
Loading