Commit Graph
2766 Commits
Author SHA1 Message Date
Kirill Ilin 08dca137de test(keycloak): cover admin console hostname split
Add helm-unittest suite asserting KC_HOSTNAME_ADMIN env, the extra
Ingress rule/TLS entry, and the appended HTTPRoute hostname are emitted
only when ingress.adminHost is set. Wire up the chart 'test' target.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-06-25 15:28:47 +05:00
Kirill Ilin 1df0e2d903 feat(keycloak): add opt-in separate admin console hostname
Add ingress.adminHost option to serve the Keycloak admin console and
admin REST API on a dedicated hostname, separate from the login/realm
hostname. When set, KC_HOSTNAME_ADMIN is configured and an additional
Ingress rule / HTTPRoute hostname routes the admin domain to the same
Keycloak service. Empty by default, keeping current behavior.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-06-25 15:28:47 +05:00
myasnikovdaniil fef9e76505 ci(renovate): pin base images and GitHub Actions to digests (#3025)
## What this PR does

Raises OpenSSF Scorecard **Pinned-Dependencies** (currently **1/10**) by
having Renovate manage and pin container base images and GitHub Actions
to immutable digests.

[PR #2849](https://github.com/cozystack/cozystack/pull/2849) SHA-pinned
actions in 13 workflows, but the Scorecard check also scores **container
base images** — 58 unpinned `FROM` lines across **27 distinct images** —
which dominate the score and keep it at 1/10. #2849 also left
`build-main.yaml` and `release-e2e.yaml` actions unpinned, and nothing
in the Renovate config kept the newly-added action SHAs updated (they
were set to rot).

### Changes

- **`.github/renovate.json`**
- Add `dockerfile` and `github-actions` to `enabledManagers` (was
`gomod`-only).
- `pinDigests: true` for both managers — Renovate opens the initial "pin
to `@sha256:`" PR (including the two workflows #2849 missed) and keeps
digests fresh thereafter.
- Batch the initial pin + all digest-only refreshes into a **single
weekly PR** (`matchUpdateTypes: ["digest", "pinDigest"]`, scheduled
Monday). Frequently-rebuilt bases (alpine, debian, golang, distroless)
would otherwise trickle in one rebuild-triggering PR each and load the
shared CI runner. Real tag bumps (major/minor/patch) are intentionally
excluded from the group so they get individual review.
- Existing `do-not-merge/hold` label + `automerge: false` are unchanged,
so every PR still requires a manual merge.

- **`packages/system/bucket/images/s3manager/Dockerfile`** — pin
floating tags to concrete versions so digest tracking doesn't churn
endlessly: `golang:1` → `golang:1.26`, `alpine:latest` → `alpine:3.24`.

### Notes

- The bulk digest pin of the 27 images is left to Renovate's first run
(one grouped PR) rather than hand-edited here, keeping this PR to the
config + tag-hygiene prerequisites.
- Expected effect once the follow-up pin PR merges: Pinned-Dependencies
**1 → ~7–8**. The remaining `downloadThenRun` / pip / npm items cap it
below 10.

### Release note

```release-note
ci(renovate): enable Renovate digest pinning for Dockerfile base images and GitHub Actions to improve the OpenSSF Scorecard Pinned-Dependencies score
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Improved automated dependency management for container images and
GitHub Actions, including clearer update grouping and digest pinning.
* Updated container base images to newer, fixed versions for more
predictable builds and deployments.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 15:02:28 +05:00
Aleksei Sviridkin 393b50de72 fix(tenant): grant watch verb to cleanup Role so pre-delete hook can wait (#2923)
## What this PR does

Two fixes to the tenant chart's `pre-delete` cleanup hook (the Job that
deletes a tenant's HelmReleases when the tenant is removed).

**1. Grant the `watch` verb so the hook stops hanging.** The hook runs
`kubectl delete helmreleases ... --wait=true`. Since Kubernetes 1.25
that flag opens a watch on the target resources to block until
finalization. The hook's Role granted only `get`, `list`, `delete`, so
the watch was rejected with HTTP 403, `kubectl delete` hung
indefinitely, the Job never finished, and tenant deletion stalled on the
pre-delete hook. Adding `watch` brings the Role in line with the
`kubernetes` app chart's cleanup Role, which already grants it for the
same `--wait` deletes.

**2. Replace the unmaintained image.** The Job ran kubectl from
`bitnami/kubectl:latest`. The bitnami Docker Hub catalog has moved to a
legacy/sunset state, so that pull is at risk of breaking — which would
stop the hook from starting at all — and `:latest` leaves the kubectl
version unpinned. It now uses `docker.io/clastix/kubectl:v1.32`, the
version-pinned image already used by every other first-party
cleanup/delete hook in the repo (kubernetes, keycloak-configure,
dashboard, mariadb). That image is Alpine-based and ships only
`/bin/sh`, so the hook script (pure POSIX) now invokes `/bin/sh` instead
of `/bin/bash`.

A helm-unittest suite pins all three invariants (watch verb, image,
shell) so none can regress.

### Screenshots

N/A — no UI impact.

### Release note

```release-note
fix(tenant): grant the watch verb to the cleanup Role and move it to a maintained kubectl image so tenant deletion no longer hangs on the pre-delete hook
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Expanded pre-delete cleanup RBAC permissions to include watching
HelmRelease resources.
* Hardened the cleanup Job runtime security settings for stronger
container confinement.
* Pinned the cleanup Job to a specific kubectl image version and
switched the command interpreter for safer execution.
* **Tests**
* Added/extended automated validation for the pre-delete cleanup hook,
covering RBAC rules, kubectl image pinning, command usage, and
securityContext hardening.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 12:29:04 +03:00
Aleksei Sviridkin 8e133a7538 fix(kubevirt): update KubeVirt to v1.8.4 (#2940)
## What this PR does

Updates kubevirt-operator from v1.8.2 to v1.8.4. This backports the VMI
checksum status-field validation fix (uint32 range) that Kubernetes 1.36
requires — without it, strict CRD numeric-format validation leaves VMIs
stuck in `Scheduled`. The release also carries assorted bug fixes and
CVE remediations. The v1.7.x line is skipped (live-migration regression,
kubevirt/kubevirt#16386).

The KubeVirt custom resource is unchanged — upstream ships a
byte-identical CR across these versions.

Verified on a dev cluster: all virt-* components roll out to v1.8.4 and
become ready.

Closes #2769

### Screenshots

Not applicable — no UI changes.

### Release note

```release-note
fix(kubevirt): update KubeVirt to v1.8.4; fixes VMIs stuck in Scheduled on Kubernetes 1.36 (strict CRD numeric-format validation of VMI checksum status fields)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Updated the KubeVirt operator version from v1.8.2 to v1.8.4, including
the corresponding deployment configuration and operator
image/environment version bumps.
* Adjusted the operator update process to download the manifest using
v1.8.4 while skipping v1.7.x.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 12:29:00 +03:00
Aleksei Sviridkin baf47ce638 chore(platform): raise Go toolchain to 1.26 across first-party images (#2941)
## What this PR does

Completes the Go-toolchain modernization for first-party images — the
build-time counterpart to #2852, which raised the root and `api/`
modules to Go 1.26.4.

1. **First-party image Go modules → go 1.26.4** (`token-proxy`,
`kube-ovn-webhook`, `kubevirt-csi-driver`): raise the `go` directive and
refresh dependencies. `kube-ovn-webhook` moves `k8s.io/*` 0.26 → 0.36.2
(only long-stable admission/core API is used); `kubevirt-csi-driver`
keeps its existing replace-based k8s alignment at 0.36.0 (main's
refactor owns that module's pin) and raises the `go` directive, with the
`golang.org/x/net` 0.56.0 security bump — which clears the reachable
GO-2026-5026 — reapplied. Adds two `.gitignore` files so the
locally-built binaries can't be committed.
2. **Go builder images → `golang:1.26`** across 8 images still on
EOL/behind toolchains (golang 1.20, 1.20.6, 1.23.4, 1.24, 1.25):
`cluster-autoscaler`, `kubevirt-cloud-provider`, `redis-operator`,
`multus-cni`, `keycloak-operator`, `objectstorage`, `kilo`,
`linstor-csi`. The builder image tag — not the go.mod minimum — sets the
standard-library version baked into the binary, so these still shipped
unpatched stdlib on a plain rebuild.

Verified: `GOOS=linux go build`/`go vet` pass for all three modules and
`go mod tidy` is a no-op; the three biggest builder jumps
(redis-operator, kubevirt-cloud-provider, cluster-autoscaler — all
formerly Go 1.20.x/1.23.x) were verified with a local `docker build`;
the remaining five (1.24/1.25 → 1.26) are covered by CI image builds.

### Release note

```release-note
chore(platform): raise the Go toolchain to 1.26 across first-party images to clear standard-library security advisories
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Updated several container build environments to a newer Go release for
consistency across Kubernetes-related components.
* Refreshed module and dependency versions in a few services to keep
builds current.
* Expanded ignore rules for generated image artifacts so build outputs
aren’t tracked.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 12:28:58 +03:00
Aleksei Sviridkin 7214efc8e5 refactor(platform): factor the cozystack-version stamp into a shared migration helper (#2980)
## What this PR does

Every migration that stamps the `cozystack-version` ConfigMap must carry
the `platform.cozystack.io/no-delete=true` label so the
`cozystack-no-delete-guardrail` ValidatingAdmissionPolicy guards it. The
chart template renders the labeled ConfigMap only on first install, so
each upgrade-time stamp has to re-emit the label by hand — migration 43
had to inline-copy migration 42's heredoc to avoid a label-less apply by
the same field manager stripping it. The bug class was patched
per-migration, not eliminated.

This extracts the stamp into a shared, sourced helper
(`render_cozystack_version_manifest` + `stamp_cozystack_version`) under
`images/migrations/migrations/lib/`, and routes migrations 42, 43, 44
and the `run-migrations.sh` bootstrap path through it. The labeled
manifest now has a single definition, so future migrations cannot drift
back to a label-less apply.

The upgrade path is behavior-preserving: the rendered manifest is
byte-identical to the previous heredocs (pinned by a golden unit test).
The bootstrap path in `run-migrations.sh` previously created the
ConfigMap without the label — it now carries it like every
migration-driven stamp.

Adds `hack/cozystack-version-stamp.bats` (8 tests) covering the helper:
label presence, ConfigMap name, quoted-string version type, namespace
default and override, required-argument guard, and the byte-exact golden
manifest.

Closes #2781

### Release note

```release-note
fix(platform): always stamp the platform.cozystack.io/no-delete label on the cozystack-version ConfigMap, including the migration bootstrap path, so deletion protection cannot be silently dropped
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **Tests**
* Expanded validation to confirm the version-stamp manifest is parseable
YAML, includes the required no-delete label, targets the correct
`cozystack-version` ConfigMap, and quotes the version value correctly.
* Added coverage for default and overridden namespaces, argument
validation failures, and a golden “byte-for-byte” render check.
* Added a guardrail test to prevent bypassing the shared stamping logic
by direct `kubectl` ConfigMap stamping.

* **Refactor**
* Centralized `cozystack-version` rendering and stamping into a shared
helper and updated migrations and the migrations runner to use it
consistently.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 12:28:54 +03:00
Aleksei Sviridkin 5be9bd5743 fix(kamaji): close Go stdlib and module CVEs in the shipped binary (#3033)
## What

Rebuild the kamaji image and force the fixed versions of three Go
modules whose advisories are compiled into the manager binary. Two build
changes:

- Advance the build source from `26.3.5-edge` to `26.3.6-edge`,
recompiling on the current `golang:1.26` toolchain (1.26.4) to close the
Go stdlib advisories.
- After applying the source patches and before `go build`, run `go get
golang.org/x/net@v0.55.0 golang.org/x/crypto@v0.52.0
go.opentelemetry.io/otel/sdk@v1.43.0 && go mod tidy` to pull the patched
module versions into the build.

## Why

The pinned image is flagged for a set of CVEs that fall into three
groups:

- 16 OS-package findings (libpython, libexpat, gnutls, krb5, sqlite,
curl, libgcrypt, libcap, nghttp2). The base is
`gcr.io/distroless/static:nonroot`, which ships no OS packages, so these
do not apply to the image — false positives.
- 1 `stdlib` finding: the binary was compiled with a go1.26 patch older
than 1.26.4. The `26.3.6-edge` rebuild on the current toolchain closes
it (crypto/x509 CVE-2026-27145, mime CVE-2026-42504, net/textproto
CVE-2026-42507).
- Go-module advisories that, unlike the OS-package noise, are genuinely
present in the compiled binary. `26.3.6-edge` pins `golang.org/x/net
v0.51.0`, `golang.org/x/crypto v0.49.0` and
`go.opentelemetry.io/otel/sdk v1.41.0`, all carrying published
advisories:
- `golang.org/x/net` < 0.55.0: CVE-2026-42506, CVE-2026-42502,
CVE-2026-39821, CVE-2026-25680, CVE-2026-25681, CVE-2026-27136 (plus
CVE-2026-33814, fixed at 0.53.0). Target 0.55.0.
- `golang.org/x/crypto` < 0.52.0: 13 advisories in
`golang.org/x/crypto/ssh` (e.g. CVE-2026-39827, CVE-2026-46595,
CVE-2026-46598). Target 0.52.0.
- `go.opentelemetry.io/otel/sdk` < 1.43.0: CVE-2026-39883
(GHSA-hfvc-g4fc-pqhx), a PATH-hijack on BSD/Solaris only; the affected
code path does not run on the Linux distroless target, but the bump
clears the finding at no runtime cost. Target 1.43.0.

A source-version bump cannot close the module advisories: no kamaji edge
tag up to `26.6.4-edge` ships the fixed module versions (it still pins
x/net 0.53.0, x/crypto 0.51.0, otel/sdk 1.41.0), and the tags that
advance the k8s line to 1.36 regress tenant control-plane RBAC. Forcing
the modules during the build is the minimal correct lever, and the
overlay already triggers a fresh compile, so it subsumes the stdlib
rebuild.

## Verification

Built the image source end to end: extracted `26.3.6-edge`, applied the
patch, ran the overlay (`go get` + `go mod tidy`, clean), and compiled
with `CGO_ENABLED=0 go build -a -o kamaji main.go`. The build succeeds
and `go version -m` on the binary embeds `golang.org/x/net v0.55.0`,
`golang.org/x/crypto v0.52.0` and the `go.opentelemetry.io/otel` set at
v1.43.0. The source has no `vendor/` directory, so `go get` + `go mod
tidy` is sufficient. Advisory IDs and fixed boundaries verified against
the OSV database.

After this change the shipped binary carries no Go advisory with an
available fix; the only residual scanner entries are in
`k8s.io/kubernetes` with no upstream fix, which no version bump can
close.

Closes #2885


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
  * Updated the Kamaji image version to a newer patch release.
* Refreshed several bundled Go dependencies to newer pinned versions
before building.



<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 12:28:51 +03:00
myasnikovdaniil 0f1cc548b5 fix(objectstorage-controller): converge BucketClaim readiness and speed up COSI provisioner failover (#3034)
## What this PR does

Fixes two failure modes in the COSI control plane built from upstream
container-object-storage-interface v0.2.2, both carried as image
patches.

**BucketClaim never converges to ready (#3032).** The controller does
not watch Bucket objects, and the generic controller drops no-op resync
deltas, so a BucketClaim whose backend Bucket flips to ready *after* the
first reconcile stayed `bucketReady=false` indefinitely — BucketAccess
was never granted and the consuming app (bucket, harbor) got no
credentials. The existing re-read of the live Bucket only ran during a
reconcile that nothing re-triggered. The controller now returns an error
while the Bucket is not ready, forcing a rate-limited requeue that
re-reads the Bucket until its readiness propagates, so the claim
converges deterministically instead of racing the async sidecar.

**Slow provisioner failover on pod recreate (part of #2429).** The
controller and the per-driver sidecar run single-replica, so leader
election adds no availability — only failover latency. The upstream 150s
lease made a recreated provisioner pod stall reconciliation for up to
~150s. The lease is lowered to the standard Kubernetes values
(15s/10s/2s), so a recreated pod resumes in ~15s. The stale unix-socket
CrashLoop in #2429 was already resolved by the seaweedfs-cosi-driver
v0.3.1 self-heal; the silent "Bucket ready with no backend bucket"
finding on that issue is a separate driver bug and is left tracked
there.

Coverage: a unit test in the patched controller pins the
requeue/propagation contract (fails without the requeue), and the
bucket/harbor e2e suites now assert `bucketReady=true` on a tight bound
instead of tolerating the lag, with scoped diagnostics on the failure
path.

Closes #3032

Refs #2429

### Screenshots

N/A — no UI changes.

### Release note

```release-note
fix(objectstorage-controller): converge BucketClaim readiness to the backend Bucket and speed up single-replica COSI provisioner failover
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved object storage bucket readiness propagation so bucket claims
now track the backend bucket’s actual `bucketReady` status and requeue
when readiness isn’t yet observed.
* Reduced and made readiness waits more reliable in end-to-end checks,
with explicit match conditions and clearer debug output (including claim
YAML, backend bucket list, and controller pod status).
* Shortened leader-election timing to speed up recovery after pod
restarts.

* **Chores**
* Updated automated PR labeling to map the object storage controller
scope to the storage area label.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 10:41:57 +05:00
myasnikovdaniil 59ded0a223 fix(kafka): set entity-operator resources to avoid OOM under tenant LimitRange (#2934)
## What this PR does

`packages/apps/kafka` rendered the Strimzi `Kafka` CR with
`entityOperator.topicOperator: {}` / `userOperator: {}` and no
`resources`. Tenant namespaces ship a `LimitRange` that defaults
containers to `memory: 128Mi`, so the topic-operator and user-operator
JVM containers (Kafka 3.9.1 + fabric8/vertx) are **OOMKilled (exit
137)** on startup. The `<cluster>-entity-operator` Deployment never
becomes Ready (CrashLoopBackOff), so:

- `KafkaTopic` / `KafkaUser` CRs never reconcile — topic creation
effectively fails;
- the cluster-operator logs `Exceeded timeout of 300000ms while waiting
for Deployment ...-entity-operator ... to be ready`;
- on teardown, `KafkaTopic`s get stuck permanently with the
`strimzi.io/topic-operator` finalizer (no operator left to clear them),
blocking namespace deletion.

The Kafka broker + ZooKeeper come up fine — only the entity-operator
dies. The `apps.cozystack.io/Kafka` schema exposes no field for
entity-operator resources, so there is no user-side workaround.

## Fix

Set explicit `resources` (requests `256Mi`/`100m`, limit `512Mi` memory)
on `entityOperator.topicOperator` and `userOperator` so they no longer
inherit the 128Mi namespace default. Adds a `helm-unittest` assertion
for the rendered limits.

## Testing

Reproduced on a clean cluster (Cozystack v1.4.3 and v1.5.0-rc.2; Strimzi
0.45.1, Kafka 3.9.1): both entity-operator containers `OOMKilled` at
128Mi → CrashLoopBackOff → `KafkaTopic` never `READY`. After bumping to
512Mi the entity-operator rolls cleanly (both containers Ready, 0
restarts) and the `KafkaTopic` reconciles to `READY=True`.

### Release note
```release-note
fix(kafka): give entity-operator (topic/user-operator) explicit resources so they no longer inherit the 128Mi tenant LimitRange default and OOMKill, which left KafkaTopics/KafkaUsers unreconciled.
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Kafka topic and user operators now use explicit CPU and memory
requests and limits, avoiding reliance on namespace-level defaults.

* **Tests**
* Added regression coverage to verify the Kafka entity operator’s topic
and user operator memory limits are explicitly set (512Mi).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 10:30:27 +05:00
Aleksei Sviridkin 5991808d28 fix(objectstorage): emit a Warning event while a BucketClaim awaits backend Bucket readiness
While the backend Bucket is not ready the controller returns an error to
force a requeue, but that error is only logged at klog.V(3) and is
suppressed at default verbosity, so an operator cannot see why the claim
is stuck. Record a WaitingForBucket Warning event on the BucketClaim on
each requeue (event aggregation folds the repetition) and still return
the error so the requeue happens as before. Pin the requeue contract in
the test by asserting the error carries the stable "not ready yet"
substring, not merely that it is non-nil.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 23:28:24 +03:00
Aleksei Sviridkin 13ca721bfd fix(kamaji): overlay patched x/net, x/crypto and otel/sdk modules
The kamaji source up to the 26.6.4-edge tag pins Go modules that carry
known advisories compiled into the manager binary: golang.org/x/net
below 0.55.0, golang.org/x/crypto below 0.52.0 and
go.opentelemetry.io/otel/sdk below 1.43.0. Unlike the distroless
OS-package findings, these advisories ship inside the Go binary and are
reported against the deployed image.

Force the fixed module versions during the build, after applying the
source patches and before compiling, so the binary embeds them. No edge
tag ships the fixes, and the tags that advance these modules also bring
the k8s 1.36 kubeadm change that regresses tenant control-plane RBAC, so
a source version bump is not a viable alternative.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 20:07:46 +03:00
Aleksei Sviridkin 7e4af79b31 fix(kamaji): rebuild image to pick up Go stdlib security fixes
The shipped kamaji binary was compiled with go1.26.3, which trivy flags
for the standard-library CVEs fixed in go1.26.4: crypto/x509
CVE-2026-27145, mime CVE-2026-42504, and net/textproto CVE-2026-42507.
The image base is distroless/static, so the remaining OS-package CVEs
from the scan do not apply to it.

Advance the build source from 26.3.5-edge to 26.3.6-edge, the next
patch on the same edge line (identical k8s.io/api v0.35.0 and
controller-runtime v0.22.4, staying clear of the k8s 1.36 line that
regresses tenant control-plane RBAC). The version change busts the
build-layer cache so the release rebuild compiles against the current
golang:1.26 toolchain, which resolves to 1.26.4 and closes the stdlib
CVEs.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 19:49:16 +03:00
Aleksei Sviridkin 250d92323d fix(objectstorage-controller): shorten COSI leader-election lease
The controller and the per-driver sidecar both run single-replica, so leader
election provides no high availability -- it only governs how quickly a freshly
recreated pod takes over. With the upstream 150s lease duration a recreated
provisioner pod stalls reconciliation for up to 150s while it waits out the
stale lease still held by the previous, now-deleted pod. Lower the lease timings
to the standard Kubernetes values (15s/10s/2s) so a recreated pod resumes
reconciliation in roughly 15s.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 19:44:58 +03:00
Aleksei Sviridkin 4437cccaf0 fix(objectstorage-controller): requeue BucketClaim until backend Bucket is ready
The dynamic-provisioning path re-reads the live Bucket after create and copies
its readiness onto the BucketClaim, but only during a reconcile. Nothing
re-drives that reconcile afterwards: the controller does not watch Buckets, and
the generic controller drops no-op resync deltas (reflect.DeepEqual), so once
the BucketClaim stops changing the listener is never re-invoked. The Bucket's
false->true transition, performed asynchronously by the sidecar on a different
object, is therefore reflected onto the claim only if the Bucket happened to be
ready during that single reconcile -- a race the sidecar usually loses, leaving
bucketReady frozen at false and BucketAccess never granted.

Return an error while the backend Bucket is not ready so the work queue
requeues the claim with exponential backoff; each retry re-reads the live
Bucket until its readiness has been propagated, converging deterministically
instead of depending on a resync that never fires.

Add a unit test pinning the contract (requeue while not ready, propagate true
once ready) and adjust the existing status-update conflict-retry test, which
pinned the old never-requeue behavior.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 19:44:45 +03:00
Aleksei Sviridkin 192246e8b6 chore(kubevirt-operator): update to v1.8.4
Refresh the vendored virt-operator manifest from v1.8.2 to v1.8.4. The
release backports validation of the VMI checksum status fields as a
uint32 range, required on Kubernetes 1.36 where strict CRD numeric
format validation otherwise leaves VMIs stuck in Scheduled. Remaining
changes are bug fixes and CVE remediations; the embedded CRDs and RBAC
are unchanged, so only the operator image tag moves.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:50:36 +03:00
Aleksei Sviridkin d09d52e8dc chore(kubevirt-csi-driver): bump golang.org/x/net to v0.56.0
Clear the reachable GO-2026-5026 advisory: idna.ToASCII is reached
through the KubeVirt client path, and the fix landed in x/net v0.55.0.
Bump to v0.56.0, pulling x/sys, x/term and x/text forward as required;
govulncheck then reports the module clean.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:44:07 +03:00
Aleksei Sviridkin 3659803dcc chore(kubeovn-webhook): ignore local build artifacts
A local `go build` emits the module-named binary (kube-ovn-webhook),
while the Dockerfile builds `-o webhook`. Ignore both names so neither
local binary is accidentally committed.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:44:07 +03:00
Aleksei Sviridkin 9c5fbb69a5 chore(images): modernize Go builder images to 1.26
Several first-party images still built their Go binaries with EOL or
behind-latest toolchains (golang 1.20, 1.20.6, 1.23.4, 1.24, 1.25), so a
plain rebuild kept shipping standard-library versions that the current
1.26 toolchain fixes. Raise every Go builder image (FROM and the
builder_image ARG defaults) to golang:1.26 across cluster-autoscaler,
kubevirt-cloud-provider, redis-operator, multus-cni, keycloak-operator,
objectstorage, kilo and linstor-csi.

This is the build-time counterpart to raising the go directive in the
first-party Go modules: the toolchain that compiles the binary, not the
go.mod minimum, determines the standard-library version baked into the
image.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:44:06 +03:00
Aleksei Sviridkin 0f33e3a60d chore(deps): bump first-party image Go modules to 1.26.4
The token-proxy, kube-ovn-webhook and kubevirt-csi-driver image modules
still pinned go 1.26.2, so their binaries shipped standard-library
versions that the 1.26.4 toolchain fixes. Raise the go directive and
refresh module dependencies to current releases.

token-proxy and kube-ovn-webhook take a full dependency refresh;
kube-ovn-webhook also moves k8s.io/* from 0.26.0 to 0.36.2 (only
long-stable admission/core API is used, so no code change is needed).
kubevirt-csi-driver keeps its existing replace-based k8s.io/* alignment
at 0.36.0 and only raises the go directive; a blanket go get -u is
avoided there because it pulls transitive bumps that break compilation
of the pinned vendored upstream csi-driver source.

Also ignore the locally-built binaries under the two image directories so
they cannot be committed by accident.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:44:06 +03:00
Aleksei Sviridkin e1f6a9c2aa fix(tenant): run the cleanup hook as non-root under a restrictive securityContext
The pre-delete cleanup Job ran kubectl as root with no securityContext.
Add a pod-level runAsNonRoot + runAsUser 65534 + seccompProfile
RuntimeDefault and a container-level allowPrivilegeEscalation: false plus
capabilities drop ALL, mirroring the dashboard adopt hook that runs the
same clastix/kubectl image non-root. Pin the securityContext in
helm-unittest.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:40:26 +03:00
Aleksei Sviridkin 5e7936c811 fix(tenant): replace bitnami/kubectl with maintained clastix image in cleanup hook
The pre-delete cleanup Job ran kubectl from `bitnami/kubectl:latest`. The
bitnami Docker Hub catalog has moved to a legacy/sunset state, so that pull is
at risk of breaking — which would stop the cleanup hook from starting at all —
and the `:latest` tag leaves the kubectl version unpinned and non-reproducible.

Switch to `docker.io/clastix/kubectl:v1.32`, the version-pinned image already
used by every other first-party cleanup/delete hook in the repo (kubernetes,
keycloak-configure, dashboard, mariadb). That image is Alpine-based and ships
only `/bin/sh`, so the hook script (pure POSIX) now invokes `/bin/sh` instead
of `/bin/bash` — matching those sibling hooks.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:40:26 +03:00
Aleksei Sviridkin ed30425b17 fix(tenant): grant watch verb to cleanup Role so pre-delete hook can wait
The pre-delete cleanup hook deletes the tenant's HelmReleases with
`kubectl delete --wait=true`, which opens a watch on helmreleases to block
until finalization. The hook Role granted only get/list/delete, so the watch
was rejected with 403, the delete call hung, the Job never finished, and
tenant deletion stalled on the hook.

Add the watch verb, matching the kubernetes app chart's cleanup Role which
already includes it for the same --wait deletes.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:40:26 +03:00
Aleksei Sviridkin de44ecf15a test(platform): enforce go-forward version stamps route through the helper
The helper header and run-migrations.sh claimed every migration-driven
stamp routes through the helper, but migrations 1-41 still stamp the
cozystack-version ConfigMap label-less and are backfilled by migration 42.
Scope the comments to go-forward stamps (migration 42 onward and the
bootstrap path), and add a unittest asserting no migration numbered >= 42
nor run-migrations.sh stamps cozystack-version without the helper, so the
no-drift invariant is enforced rather than aspirational.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:32:52 +03:00
Aleksei Sviridkin 985b4b0954 fix(platform): guard stamp_cozystack_version against a missing version
Mirror render_cozystack_version_manifest's argument guard in
stamp_cozystack_version so a missing version aborts before the kubectl
pipe. Without it, a render failure in a shell without pipefail would
leave the pipeline exit status to kubectl, which would apply empty input.
Add a unittest covering the guard.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:32:05 +03:00
Aleksei Sviridkin 3aabb0cb7c fix(platform): stamp the no-delete label on bootstrap cozystack-version
The bootstrap path that creates cozystack-version when the ConfigMap is
absent applied it without the platform.cozystack.io/no-delete label,
leaving it unguarded by the cozystack-no-delete-guardrail
ValidatingAdmissionPolicy. Route it through the shared helper so the
bootstrap ConfigMap carries the label like every migration-driven stamp.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:32:05 +03:00
Aleksei Sviridkin b199b5e438 refactor(platform): stamp cozystack-version via shared helper in migrations
Migrations 42, 43 and 44 each carried a copy-pasted heredoc that applied
the labeled cozystack-version ConfigMap. Source the shared helper and call
it instead, so the labeled manifest has a single definition and future
migrations cannot reintroduce a label-less apply.

Behavior-preserving: the rendered manifest is byte-identical to the
previous heredocs. Migration 42 keeps its MIGRATION_DRY_RUN path, now
building its manifest from the helper's pure renderer.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:32:05 +03:00
Aleksei Sviridkin 50344f1ab9 refactor(platform): add shared cozystack-version stamp helper
Extract the labeled cozystack-version ConfigMap stamp into a sourced
shell helper so migrations cannot drift back to a label-less apply that
strips the platform.cozystack.io/no-delete label.

render_cozystack_version_manifest emits the manifest on stdout (pure,
unit-testable); stamp_cozystack_version renders and applies it. The
namespace defaults to cozy-system and honors $NAMESPACE.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-24 15:32:04 +03:00
Aleksei Sviridkin 29bf56f550 chore(images): bump opencost, multus, clickhouse-backup (#2900 partial) (#3000)
## What this PR does

Bumps three of the small components listed in #2900, each picking up
published security fixes:

- **opencost** chart `1.41.0 → 2.5.23` (app `1.111.0 → 1.120.3`). The
1.x→2.x chart-major bump's values schema is additive, so the cozystack
overrides (external prometheus vmselect endpoint, customPricing) stay
valid. The Makefile now pins `--version 2.5.23` and drops the upstream
snapshot test suite (it can't resolve in the cozystack render context);
cozystack ships its own helm-unittest.
- **multus-cni** `v4.2.3 → v4.3.0`, rebuilt multi-arch (builder
`golang:1.24 → 1.26` for the Go-stdlib CVEs). This also **folds the
`multusMasterCNI: 05-cilium.conflist` CNI-ordering fix into
`customize-deployment.patch`** — it was previously a raw daemonset
hand-edit that the next `make update` would have wiped, re-introducing
the kube-ovn-before-cilium startup race. A new helm-unittest pins it.
- **clickhouse-backup tool** `altinity/clickhouse-backup 2.6.32 →
2.7.2`, rebuilt multi-arch. The separate `clickhouse-backup` image
(clickhouse-server base) and the managed clickhouse-server version are
intentionally left as-is (multi-major server upgrade, out of scope).

Each package gains helm-unittest coverage (none shipped before).

**Deferred from #2900 (this PR does NOT close the issue):**

- **bootbox** — already at the latest upstream tag (no-op).
- **kubeovn-plunger** — first-party cozystack component, no upstream
release to bump.
- **etcd-operator** — held at 0.4.5: the 0.5.x Helm chart is not
published on the `ghcr.io/aenix-io/charts` OCI registry yet (only GitHub
releases exist), so `helm pull` can't fetch it. Needs an aenix-io chart
publish first.
- **ingress-nginx** — deliberately pinned to 4.11.2 (revert `5c900a746`
after the CVE-2025-1974 mitigation attempt); bumping needs a separate
investigation, not a routine sweep.

### Release note

```release-note
chore(images): bump opencost to 2.5.23, multus-cni to v4.3.0, and clickhouse-backup to 2.7.2
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced OpenCost Helm support for plugin installation/config
validation, cloud integration (secret or JSON), MCP server, and
`extraObjects` rendering
  * Added admin token secret creation and Pod Disruption Budget options
* Expanded UI/API/MCP exposure via Ingress, OpenShift Route, and Gateway
API HTTPRoute
* Improved internal Prometheus/Thanos endpoint handling and optional CA
trust update

* **Updates**
* Updated ClickHouse backup and Multus images; adjusted Multus “thick”
deployment behavior/resources and namespace usage
  * Refreshed OpenCost chart values/docs and bumped chart/app versions

* **Tests**
* Added/extended Helm unittest suites and rendering invariants for
backup, Multus, and OpenCost
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-24 15:18:29 +03:00
Aleksei Sviridkin a74b618e69 chore(cilium): bump cilium to 1.19.5 (#2972)
## What this PR does

Bumps cilium from 1.19.3 to 1.19.5 (latest 1.19 patch), picking up the
published security fixes the issue enumerates (incl. the
`moby/spdystream` and `golang.org/x/net` updates carried by 1.19.4) plus
upstream bug fixes: CiliumEgressGatewayPolicy NamespaceSelector
corruption, BGP PeerConfig status cleanup, and a reused-endpoint BPF
state race.

The change is a single self-contained commit:

- Re-vendors the chart via `make update` (helm pull cilium 1.19.5). The
two cozystack vendoring patches re-apply cleanly — the
SYS_MODULE/iptables capability lines and the k8s<1.30 AppArmor
annotation block are stripped (the Makefile guard confirms the AppArmor
block is gone, so there is no duplicate-mapping-key risk on the agent
DaemonSet).
- Points `images/cilium/Dockerfile` at `quay.io/cilium/cilium:v1.19.5`.
- Rebuilds the cozystack agent image multi-arch (linux/amd64 +
linux/arm64) and pins it in `values.yaml` (`1.19.5@sha256:8f0e898…`),
mirroring the rebuild-and-pin step done for the 1.19.3 bump — so the
deployed agent carries the fixes immediately, not just on the next
release rebuild.

Upstream dropped the dev-only `values.yaml.tmpl` / `README.md.gotmpl`
from the 1.19.5 release tarball (hence the large deletion). The defunct
`l2podAnnouncements.interface` and `loadBalancer.standalone` removals
don't affect cozystack, which uses neither.

Verified: `helm template` renders the agent at `1.19.5@sha256:8f0e898…`
across the talos/kilo/kubeovn/apparmor overlays; `helm lint` passes
aside from the expected wrapper-chart dependency artifact.

Closes #2893

### Release note

```release-note
chore(cilium): bump cilium to 1.19.5
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Upgraded the Cilium Helm chart to **1.19.5** and refreshed default
container images/digests across components.
  * Adjusted Helm packaging to exclude `*.tmpl`/`*.gotmpl` artifacts.
* **New Features**
  * Expanded RBAC to include **BGP peering policy** resources.
* Updated **L2 pod announcements** configuration to use
`interfacePattern`.
* **Bug Fixes**
* Improved ingress EndpointSlice readiness/labels for more consistent
endpoint behavior.
* Enabled IPv6 traffic to fall back to the kernel stack when the IPv6
datapath is disabled.
* **Refactor**
* Made the operator health `hostPort` configurable based on host
networking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-24 15:13:15 +03:00
Myasnikov Daniil 56108eca83 ci(renovate): pin base images and GitHub Actions to digests
Enable Renovate's dockerfile and github-actions managers with
pinDigests so OpenSSF Scorecard Pinned-Dependencies (currently 1/10)
can pass and supply-chain refs stay reproducible.

PR #2849 SHA-pinned actions in 13 workflows, but the check also scores
container base images -- 58 unpinned FROM lines across 27 distinct
images -- and left build-main.yaml / release-e2e.yaml unpinned.
Nothing kept the new action SHAs updated either, so they would
silently stop receiving security patches.

Enabling the managers lets Renovate open the initial pin PR (and pin
the two missed workflows) and keep digests fresh thereafter.
Digest-only refreshes and the initial pin are batched into a single
weekly PR to avoid a trickle of rebuild-triggering PRs on the shared
CI runner; real tag bumps stay individual for review.

Also pin s3manager's floating tags (golang:1, alpine:latest) to
concrete versions first, otherwise digest tracking churns endlessly.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-06-24 12:07:49 +05:00
Aleksei Sviridkin 6df2b3a797 chore(packages/system/cilium): bump cilium to 1.19.5
Re-vendors the cilium chart from 1.19.3 to 1.19.5 (latest 1.19 patch) and
points the agent image build at v1.19.5. Picks up the published security
fixes plus upstream bug fixes (CiliumEgressGatewayPolicy NamespaceSelector
corruption, BGP PeerConfig status cleanup, reused-endpoint BPF state race).

The make-update vendoring patches re-apply cleanly: the SYS_MODULE/iptables
capability lines and the k8s<1.30 AppArmor annotation block are stripped (the
guard confirms the AppArmor block is gone, and the rendered agent DaemonSet
carries the annotation exactly once via cozystack podAnnotations). Upstream
dropped the dev-only values.yaml.tmpl / README.md.gotmpl from the 1.19.5
release tarball. The defunct l2podAnnouncements.interface removal does not
affect cozystack, which uses interfacePattern.

The BPF host patch (pass-ipv6-to-stack-when-ipv6-datapath-disabled.diff) is
refreshed against v1.19.5 bpf_host.c: identical logic, only context lines
re-synced.

The deployed agent image pin in values.yaml is intentionally left on the
current release-line digest; the multi-arch cilium agent is rebuilt and
re-pinned during release preparation.

Adaptations:
- charts/: re-vendored (helm pull cilium 1.19.5 + capability/AppArmor patches)
- images/cilium/Dockerfile: ARG VERSION v1.19.3 -> v1.19.5
- images/cilium/patches/: BPF host patch context refreshed for v1.19.5

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-23 15:04:51 +03:00
Aleksei Sviridkin 1b4c8b6246 chore(kilo): rebuild kilo image on current upstream and alpine 3.24
Rebuilds the first-party kilo image to clear the published libpng advisories
carried by the stale pinned layers and to pick up current upstream:

- ARG VERSION: squat/kilo main fbce60d8 -> 944dff57 (the rebuild also refreshes
  the golang:1.25 stdlib compiled into the kg / kgctl binaries)
- runtime and cni base: alpine 3.23 -> 3.24, which clears the libpng16-16 /
  libpng advisories pulled in through the graphviz / font-noto chain
- CNI plugins: v1.9.0 -> v1.9.1
- values.yaml: re-pinned to the rebuilt multi-arch digest; the tag handle moves
  from latest to v<version> to match the sibling first-party images

The in-repo cross-mesh-granularity feature patch still applies cleanly on the
new HEAD and is verified in the built binary (kg --mesh-granularity lists
`cross`). Adds the package's first helm-unittest coverage, pinning the image
ref and the default mesh-arg wiring.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-23 14:39:53 +03:00
Aleksei Sviridkin 7532cf59f9 chore(packages/apps/clickhouse): bump clickhouse-backup tool to 2.7.2
Rebuilds the altinity-clickhouse-backup sidecar image off the upstream
altinity/clickhouse-backup 2.6.32 -> 2.7.2 release (multi-arch) and pins the
new digest. Picks up the published security fixes in the backup tool. The
clickhouse-server version (24.9.2) is intentionally left as-is: moving it is a
multi-major server upgrade, out of scope for this maintenance bump.

Extends the existing backup helm-unittest to assert the sidecar image tag, so
the bump is guarded against regressions.

Adaptations:
- images/altinity-clickhouse-backup/Dockerfile: FROM altinity/clickhouse-backup 2.6.32 -> 2.7.2
- images/altinity-clickhouse-backup.tag: pin rebuilt multi-arch image digest
- tests/backup_test.yaml: assert the backup sidecar image tag

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-23 14:39:14 +03:00
Aleksei Sviridkin c50b73fd9c chore(packages/system/multus): bump multus-cni to v4.3.0
Re-vendors the multus-cni thick-mode daemonset from upstream v4.2.3 to v4.3.0
and rebuilds the cozystack image (multi-arch, golang:1.26 builder; v4.3.0's
go.mod and the published security fixes warrant the stdlib bump from 1.24). The
fix-del-without-cache and customize-deployment patches both re-apply cleanly to
v4.3.0. The rebuilt image is pinned by digest in the daemonset.

Folds the previously hand-edited `multusMasterCNI: "05-cilium.conflist"`
CNI-ordering fix into customize-deployment.patch so it survives every make
update (it was a raw daemonset edit that the re-vendor would otherwise wipe,
re-introducing the kube-ovn-before-cilium startup race).

Adds helm-unittest coverage (the package shipped none): asserts the daemonset
runs the cozystack-built image and that the daemon-config pins multusMasterCNI
to the cilium conflist.

Adaptations:
- images/multus-cni/Dockerfile: builder golang:1.24 -> 1.26, ARG VERSION v4.2.3 -> v4.3.0
- templates/multus-daemonset-thick.yml: re-vendored v4.3.0 + customize patch; pin rebuilt multi-arch image
- patches/customize-deployment.patch: carry the multusMasterCNI CNI-ordering fix
- Makefile: add test target
- tests/multus_test.yaml: new helm-unittest coverage

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-23 14:39:14 +03:00
Aleksei Sviridkin 4d507d1456 chore(packages/system/opencost): bump opencost chart to 2.5.23
Re-vendors the opencost chart from 1.41.0 to 2.5.23 (app 1.111.0 -> 1.120.3),
crossing the 1.x -> 2.x chart-major boundary, picking up the published security
fixes. The major bump's values-schema changes are additive (new clusterName,
pdb, extraObjects keys; no removals), so the cozystack overrides (external
prometheus vmselect endpoint, customPricing) stay valid -- confirmed by render.

Pins the update target to --version 2.5.23 and drops the upstream chart's own
snapshot-based helm-unittest suite (it fails in the cozystack render context).
Adds cozystack helm-unittest coverage: pins the image and the prometheus
endpoint wiring.

Adaptations:
- charts/: re-vendored via make update (helm pull opencost --version 2.5.23; upstream tests removed)
- Makefile: pin --version 2.5.23; add test target; strip upstream chart tests
- tests/opencost_test.yaml: new helm-unittest coverage

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-06-23 14:39:14 +03:00
scooby87 0e2e6e19f0 feat(harbor): bump chart to 1.19.1 (Harbor 2.15.1) (#2966)
Bump the vendored Harbor Helm chart from 1.18.2 to 1.19.1, which
upgrades Harbor itself from appVersion 2.14.2 to 2.15.1.

The bump adds PodDisruptionBudget templates for the core, exporter,
jobservice, nginx, portal, registry and trivy components, improving
availability during voluntary disruptions (node drains/upgrades).

<!-- Thank you for making a contribution! Here are some tips for you:
- Use Conventional Commits for the PR title: `type(scope): description`
- Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
- Scopes are not an exhaustive list — pick the most specific scope for
the change and extend the list when a genuinely new area appears.
Examples:
- System components: dashboard, platform, operator, cilium, kube-ovn,
linstor, fluxcd, cluster-api
- Managed apps: postgres, mariadb, redis, kafka, clickhouse,
virtual-machine, kubernetes
- Development and maintenance: api, hack, tests, ci, docs, maintenance
- Breaking changes: append `!` after type/scope (`feat(api)!: ...`) or
add a `BREAKING CHANGE:` footer
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Screenshots

<!-- REQUIRED for UI changes: attach screenshots or screen recordings
demonstrating
the visual impact of your changes. PRs with UI changes without
screenshots will not be merged. -->

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same `type(scope):` prefix as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
feat(harbor): bump Harbor to 2.15.1 and add PodDisruptionBudgets for core, portal, jobservice, nginx, registry, trivy and exporter
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added Pod Disruption Budget support for core, portal, jobservice,
nginx, registry, trivy, and exporter.
* Made container health checks (liveness/readiness, plus core startup)
fully configurable per component.
  * Added configurable registry HTTP client timeout.
* Enhanced Gateway API route configuration (hostnames formatting and
backend reference details).

* **Improvements**
* Improved external Redis credential handling for registry usage (safer
secret guarding and URL-encoding).
  * Updated Harbor chart metadata and component images to **v2.15.1**.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Closes #2880
2026-06-23 14:32:43 +03:00
Aleksei Sviridkin 2a5ccf1d4d chore(monitoring): bump Grafana to 11.6.15, victorialogs datasource and alerta (#3011)
## What this PR does

Refreshes the `system/monitoring` image anchors onto current upstream to
clear the published advisories (8 CVEs, 1 critical) carried by the stale
pins.

- **grafana image**: base `grafana/grafana` `11.4.0` → `11.6.15` (latest
11.x). The rebuild clears the Go-dependency advisories in the grafana
binary (`x/crypto`, `moby/spdystream`, `jackc/pgx/v5`,
`russellhaering/goxmldsig`, `buger/jsonparser`, `golang-jwt/jwt/v4`,
`getkin/kin-openapi`). It stays on the 11.x line rather than 12.x to
keep the bundled panel plugins compatible (`grafana-worldmap-panel` is
deprecated upstream) and avoid a dashboard-schema migration.
- **victorialogs-datasource** plugin: `v0.14.1` → `v0.28.0`
(`grafanaDependency >=10.4.0`, so it loads on 11.6.15).
- **alerta-web**: `9.0.4` → `9.1.0`, clearing the python `cryptography`
advisory.
- `images/grafana.tag`: re-pinned to the rebuilt multi-arch digest
(`linux/amd64` + `linux/arm64`).

The built grafana image was verified in place: grafana `11.6.15`, all
four plugins present (`natel-discrete-panel`, `grafana-worldmap-panel`,
`marcusolsson-dynamictext-panel`, `victoriametrics-logs-datasource`),
vlogs `0.28.0`. helm-unittest passes (4/4).

Closes #2892

### Release note

```release-note
chore(monitoring): bump Grafana to 11.6.15, victorialogs-datasource to v0.28.0 and alerta-web to 9.1.0
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated Grafana monitoring dashboard base image to 11.6.15 and
VictoriaLogs datasource plugin to v0.28.0
  * Upgraded Alerta monitoring and alerting tool to 9.1.0

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:14:24 +03:00
Aleksei Sviridkin 2494843599 chore(testing): refresh e2e-sandbox tools and base to current upstream (#3010)
## What this PR does

Rebuilds the e2e test sandbox on current upstream to clear the published
advisories (containerd, helm, go-git, moby/spdystream, Go stdlib)
carried by the stale tool binaries and base layers.

- base: `ubuntu:22.04` → `24.04`; `netcat` → `netcat-openbsd` (on 24.04
`netcat` is a candidate-less virtual package, so the concrete provider
must be named)
- kubectl: `1.33.2` → `1.33.13` — stays on the 1.33 line that the e2e
control plane pins at `v1.33.12` (`hack/e2e-prepare-cluster.bats`), so
client/server skew is unchanged
- talosctl: `1.10.4` → `1.13.5` — aligns the client with the v1.13.x
Talos nodes the sandbox provisions
- helm: `3.18.3` → `3.21.2` (latest helm 3) — the e2e flow drives the v3
CLI, so it stays on the 3.x line rather than moving to the breaking 4.x
- yq: `4.44.3` → `4.53.3`
- `values.yaml`: re-pinned to the rebuilt multi-arch digest
(`linux/amd64` + `linux/arm64`)

`crust-gather` and `cozyhr` already track their latest releases; `flux`
and `mc` install the current release at build time. The built image's
tool versions were verified in place (kubectl `v1.33.13`, talosctl
`v1.13.5`, helm `v3.21.2`, yq `v4.53.3`, flux `2.8.8`, ubuntu `24.04`).

Closes #2891

### Release note

```release-note
chore(testing): refresh e2e-sandbox tools and base (ubuntu 24.04, kubectl 1.33.13, talosctl 1.13.5, helm 3.21.2)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Updated the e2e sandbox image to a new fixed digest for more
consistent test runs.
* Refreshed the sandbox build environment (Ubuntu 24.04) and upgraded
tooling (Kubernetes, Talos, Helm, and yq) to newer stable versions.
* Improved OS package setup by switching from `netcat` to
`netcat-openbsd` and consolidating apt cleanup to reduce image size.
* **Documentation**
* Updated e2e testing guidance: removed the recommendation to pin the
management cluster Kubernetes version, and added guidance to
snapshot/restore cluster state between test groups.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:14:20 +03:00
Aleksei Sviridkin bebf4db0df chore(build): refresh first-party Alpine runtime bases to 3.24 (#3009)
## What this PR does

Moves the pinned Alpine runtime bases of the first-party images forward
to `alpine:3.24`, clearing the published `musl` / `zlib` advisories
carried by the stale layers.

| image | base |
| --- | --- |
| mariadb-backup | 3.20 → 3.24 |
| cozystack-operator | 3.22 → 3.24 |
| platform-migrations | 3.22 → 3.24 |
| grafana-dashboards | 3.22 → 3.24 |
| kubeovn-webhook | 3.21.3 → 3.24 |
| redis-operator | latest → 3.24 |

Each runtime `apk` set was verified to resolve on `alpine:3.24`. These
images rebuild on the release asset pipeline, which re-pins the digests
in `values.yaml` on the next build — matching how the rest of the ~30
first-party images pick up the shared base (the issue's "rebuild and run
the standard test pipeline").

**Scope notes:**

- The build-only `alpine AS source` stages (keycloak-operator,
objectstorage-controller) are left as-is: their final images are
distroless, so no Alpine layer ships.
- The s3manager base is owned by the separate bucket bump (#2887), and
kilo's base moves in its own image rebuild (#2898).
- **Side effect for platform-migrations**: its `kubectl` / `helm` come
from the Alpine repo, so the base bump moves them `1.33 → 1.36` and
`3.18 → 3.19`. Both are current upstream stable and in skew with the
modern control plane for the migration scripts' operations (apply / get
/ label / helm release ops).

Closes #2902

### Release note

```release-note
chore(images): refresh first-party Alpine runtime bases to 3.24 to clear the musl/zlib advisories
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Updated Alpine Linux base images across multiple application
containers to version 3.24 (including backup utilities,
platform/operator components, monitoring dashboards, and
networking/webhook components) to improve security and build
consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:14:15 +03:00
Aleksei Sviridkin e83ba4e298 chore(coredns): refresh coredns chart to 1.46.0 (#3004)
## What this PR does

Re-vendors the CoreDNS Helm chart from `1.43.2` to `1.46.0` (chart
`appVersion` `1.12.3` → `1.13.1`) and pins the `make update` target to
`--version 1.46.0` so re-vendoring is reproducible (it was previously
tracking upstream `latest` silently).

The running CoreDNS **image is deliberately kept** at
`registry.k8s.io/coredns/coredns:v1.12.4`. It is pinned to the 1.12 line
that matches the Kubernetes-bundled kube-dns replacement, and v1.12.4 is
the latest patch of that line (itself a security release). The
cozystack-side `values.yaml` pins `coredns.image.tag: v1.12.4`, so the
chart's `appVersion` bump never reaches the deployed container — the
rendered Deployment still uses `v1.12.4`. The kube-dns overrides
(`k8sAppLabelOverride`, `service.name`, `serviceAccount.name`) stay
valid.

The new chart template logic (`dnsConfig`/`dnsPolicy`, ServiceMonitor
`scrapeTimeout`/`scheme`/`honorLabels`/`tlsConfig`/relabelings,
multicluster RBAC, `customAnnotations`, `automountServiceAccountToken`)
is inert under the cozystack values — none of those keys are set, so
every new conditional is skipped and the bump is behavior-neutral for
the pinned configuration.

This references #2899 but does **not** close it: that ticket asks to
advance the CoreDNS *image* for CVE remediation, which conflicts with
the kube-dns version alignment. Whether to move the bundled CoreDNS line
forward (and thus the image) is a platform-level call, left open on the
issue.

### Release note

```release-note
chore(coredns): refresh vendored CoreDNS chart to 1.46.0 (image held at v1.12.4 for kube-dns alignment)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added DNS policy and custom DNS configuration options for deployments
  * Introduced pod labels support for custom pod labeling
* Expanded Prometheus monitoring with scrape timeout, TLS configuration,
and relabeling options
  * Added multicluster RBAC support capability

* **Chores**
  * Updated CoreDNS to version 1.13.1
  * Bumped Helm chart version to 1.46.0

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:14:10 +03:00
Aleksei Sviridkin fbf6415dbe chore(hami): bump HAMi to 2.9.0 (#2993)
## What this PR does

Re-vendors the HAMi vGPU chart from 2.8.1 to 2.9.0, moving the
device-plugin and scheduler-extender images to `projecthami/hami:v2.9.0`
and picking up the published security fixes.

**Vendoring approach changed for 2.9.0.** Upstream now gates the
scheduler and device-plugin templates on `.Values.dra.enabled` and
`.Values.podSecurityPolicy.enabled` across ~27 files, so the previous
approach (strip the dra/PSP values and remove the conditionals by hand)
would nil-pointer at render time. Instead the `dra:` and
`podSecurityPolicy:` blocks are KEPT at their upstream default
(`enabled: false`), which cleanly disables both paths; only the unused
`hami-dra` subchart and its values block are removed. The Makefile
vendoring notes are updated to document this.

Replays the `indent`→`nindent` patch on the custom Service labels block
— now extended to **both** Services that carry the upstream defect: the
device-plugin monitor Service and the scheduler Service (the latter was
previously unpatched and would emit invalid YAML if
`scheduler.service.labels` were set).

Adds helm-unittest coverage (the package shipped none): pins the
device-plugin image and guards the nindent patch on both Services. `helm
unittest` 3/3 pass.

Note: the vendored `charts/hami/README.md` still documents the old
`global.imageTag` default — that is an upstream autogenerated-doc bug
carried in by `make update`; per the vendoring policy it is left
untouched (the operative `values.yaml` default is correctly `v2.9.0`).

Closes #2897

### Release note

```release-note
chore(hami): bump HAMi to 2.9.0
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added DRA (Dynamic Resource Allocation) support with feature flag
  * Added Vastai device support
  * Added Prometheus ServiceMonitor templates for metrics collection
  * Enhanced scheduler with Kubernetes 1.22+ native API support

* **Improvements**
  * Upgraded HAMi to v2.9.0
  * Expanded Ascend device configuration options
  * Added legacy metrics compatibility mode
  * Improved PodSecurityPolicy support
  * Enhanced service selector labels for better traffic routing

* **Tests**
* Added chart rendering tests for version verification and label
validation

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:14:06 +03:00
Aleksei Sviridkin 9e57b8d103 chore(foundationdb-operator): bump fdb-operator to v2.30.0 (#2992)
## What this PR does

Re-vendors the FoundationDB Kubernetes operator chart from v2.13.0 to
v2.30.0 (chart 0.2.0 → 0.3.0), 17 minor releases forward, picking up the
published security fixes the issue enumerates. The operator +
init-monitor images advance to the current upstream tags that carry the
patched base packages.

The vendored tree is byte-identical to a fresh upstream `v2.30.0` clone
(templates + values + the three CRDs copied from `config/crd/bases/`).
The CRD changes are **additive only** — new fields, no property removals
(only the controller-gen / `foundationdb.org/release` version
annotations change) — so the `apps/foundationdb` FDB CR stays valid
against the new operator. cozystack overrides (`globalMode`,
`nodeReadClusterRole`) remain valid and consumed by the v2.30.0
templates. The one removed CLI flag (`genericclioption`) is not used by
cozystack; the chart's RBAC role binding is now unconditional
(previously globalMode-gated) — a no-op for cozystack, which sets
`globalMode=true`.

Adds helm-unittest coverage (the package shipped none): pins the
operator image.

Verified: `helm template` renders the operator at `v2.30.0`; `helm
unittest` 1/1 pass.

Closes #2879

### Release note

```release-note
chore(foundationdb-operator): bump fdb-operator to v2.30.0
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for custom environment variables plus additional pod
volumes and mounts for the operator.
* Expanded FoundationDB backup/cluster/restore CRD capabilities (new
backup modes, deletion policies, workload references, and pod template
options).

* **Bug Fixes**
* Adjusted RBAC service account binding behavior to use the release
namespace consistently.

* **Tests**
* Added image pin and global-mode rendering checks for operator
deployment.

* **Chores**
* Upgraded the FoundationDB operator Helm chart/app version and image to
v2.30.0; added a Helm unittest `test` target.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:14:01 +03:00
Aleksei Sviridkin f8a648abdc chore(openbao): bump openbao chart to 0.25.7 (#2991)
## What this PR does

Re-vendors the openbao-helm chart from 0.25.3 to 0.25.7 (appVersion
v2.5.0 → v2.5.1), the latest in the `^0.25` line the Makefile pins. The
vendored tree is byte-identical to a fresh upstream pull; cozystack
overrides (`injector.enabled: false`, `csi.enabled: false`) are
untouched and still render nothing, so the changed runtime surface is
the openbao server StatefulSet image.

**Security scope (honest accounting):** v2.5.1 fixes two OpenBao CVEs —
including the critical **CVE-2025-68121** (Go stdlib TLS, CVSS 10.0, via
a Go 1.25.7 rebuild) and **CVE-2026-24051** (otel/sdk). The issue also
lists `github.com/jackc/pgx/v5` — that is **not** addressed: pgx is
unchanged in v2.5.1 upstream, so it can't be closed by an in-`^0.25`
bump. `libcap2`/`libexpat` are base-image packages picked up
incidentally by the rebuild (not verified here). Widening past 0.25.x to
0.28.x (app v2.5.5) would need a CHART_VERSION constraint change plus a
0.26/0.27/0.28 changelog review and is intentionally left out.

Adds helm-unittest coverage (the package shipped none): pins the server
image and the injector/CSI-disabled invariants. `helm unittest` 3/3
pass.

Closes #2895

### Release note

```release-note
chore(openbao): bump openbao chart to 0.25.7 (app v2.5.1, fixes critical CVE-2025-68121)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for configuring headless service annotations (including
HA standby headless service).
* Enhanced the Grafana dashboard with consistent dynamic job filtering
across Prometheus queries.
* **Updates**
  * Upgraded Helm chart to **0.25.7** (OpenBao app **v2.5.1**).
  * Updated snapshot agent image tag to **0.3.0**.
* **Tests**
* Added Helm unit test coverage via a `helm unittest` Makefile target
and new chart rendering invariants.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:13:57 +03:00
Aleksei Sviridkin 491b184948 feat(cozy-lib): add CA-only TLS trust-anchor helper for tenants (#2989)
## What this PR does

Part of #2814. Part of #2811.

This is the foundational ("keystone") piece of WS3: a canonical,
reusable trust-anchor object that lets a tenant obtain `ca.crt` to
verify a per-app TLS endpoint **without** read access to any object that
also carries a private key. It unblocks the per-app TLS series (WS4/WS5)
by giving every chart one agreed, key-free delivery shape instead of
each chart inventing its own.

### The problem (verified against current `main`)

Per-app TLS issues a per-release, self-signed CA. The only objects that
hold `ca.crt` today also hold private keys:

- the cert-manager CA Secret `<release>-ca` carries the CA private key
(`tls.key`) — full trust-chain compromise if leaked
(`packages/apps/nats/templates/certmanager.yaml`, the `isCA`
Certificate);
- the cert-manager leaf Secret `<release>-tls` carries the server
private key (`tls.key`) plus `ca.crt` (same file, the leaf Certificate);
- CNPG surfaces `ca.crt` only inside its user-credentials Secret
(`packages/apps/postgres/templates/db.yaml`, the operator-managed TLS
block).

So any RBAC path that hands a tenant `ca.crt` by granting read on one of
those Secrets also hands over a private key. On `main` today the
cert-manager apps grant tenants no access to those Secrets at all, so a
tenant currently cannot obtain `ca.crt` to verify the server — the gap
this object closes safely.

### Design decision: key-free Opaque object delivered through
`tenantsecrets`, not trust-manager

I evaluated the two candidate delivery mechanisms.

**Rejected — trust-manager.** A trust-manager `Bundle` reads its sources
only from trust-manager's single configured "trust namespace"; its
`namespaceSelector` governs only where the bundle is *distributed to*,
not where it is *sourced from*. A per-release self-signed CA lives in
the tenant namespace, so trust-manager cannot use it as a source, and
projecting one shared CA to all tenants would defeat per-release
isolation. I re-verified this against current upstream docs
(cert-manager.io trust-manager) and the open per-namespace-trust-bundle
request (cert-manager/trust-manager#131, which is target-side only). The
prior analysis still holds.

**Chosen — a `ca.crt`-only Opaque Secret surfaced through the existing
tenant-secret API.** This generalizes the reference pattern from the
redis work (#2729), where the operator publishes a CA-only Opaque Secret
and RBAC is scoped to it instead of to the CA-private-key Secret. The
new `cozy-lib.tls.caCertSecret` helper renders that object once,
identically, for every chart:

- `type: Opaque`, a single `ca.crt` data key, no `tls.key`/`tls.crt`;
- label `internal.cozystack.io/tenantresource: "true"`;
- fails closed on empty input and refuses any PEM that contains private
key material.

### How the RBAC wiring works (no new roles needed)

The label is the entire mechanism, and it routes through RBAC that
already exists:

- `pkg/registry/core/tenantsecret/rest.go` surfaces, under the virtual
resource `core.cozystack.io/tenantsecrets`, exactly the namespace
Secrets bearing `internal.cozystack.io/tenantresource=true`
(`buildTenantSelector`, lines 199-213; label constants
`pkg/apis/core/v1alpha1/tenantresource_types.go:3-4`; full `Data` copied
through by `secretToTenant`, lines 84-103).
- `packages/system/cozystack-basics/templates/clusterroles.yaml` grants
`get/list/watch` on `core.cozystack.io/tenantsecrets` to tenant
ServiceAccounts via `cozy:tenant:base` (lines 44-47) and to
`use`/`admin`/`super-admin` subjects via `cozy:tenant:use:base` (lines
179-180). None of this touches raw core `secrets`, so attaching the
label to a key-free object exposes the trust anchor and nothing else.
- `internal/backupcontroller/credentials_projector.go:128-133` relies on
the same rule in reverse — it deliberately *omits* the label so its
key-bearing projection is not promoted to a `TenantSecret`. This helper
is the positive counterpart: a key-free object that is safe to promote.

`view` deliberately does not receive the trust anchor through this path:
`cozy:tenant:view:base` grants only `core.cozystack.io/options` (lines
120-126), and `tenantsecrets` also includes credential Secrets, so
granting it to a read-only role would leak passwords. The trust anchor
reaches `use` and above plus tenant ServiceAccounts — the same access
level at which connection credentials are already surfaced (the
per-release dashboard Role binds at `use`, e.g.
`packages/apps/postgres/templates/dashboard-resourcemap.yaml` via
`cozy-lib.rbac.subjectsForTenantAndAccessLevel`). A chart that must show
`ca.crt` at `view` level in the dashboard can additionally name the
key-free Secret in its own per-release Role; that is a per-app detail,
not a base-role change.

### Why a library helper and not a controller here

Populating `ca.crt` stays the responsibility of whatever owns the PKI —
the app operator (as the redis fork does) or a cert-manager chain
resolved at the chart level. The helper is intentionally pure and
value-driven so it renders deterministically and is the single shape
every per-app PR converges on. A shared key-stripping projection
controller is a reasonable future generalization but is out of scope for
this foundational object.

### Convergence plan for the per-app TLS series (follow-up, not this PR)

I did not modify any of the open per-app branches. Each should adopt the
canonical object as follows:

- redis #2729 — already publishes an operator-side CA-only Opaque Secret
and already drops the grant on the CA-private-key Secret; converging
means emitting it through the helper / carrying the `tenantresource`
label so delivery matches the rest of the catalog.
- nats, qdrant (merged, cert-manager) — emit the canonical object via
the helper and withhold `<release>-ca` / `<release>-tls` from tenants.
- mariadb #2680, opensearch #2682, rabbitmq #2683, mongodb #2692 — same:
emit the canonical object, never grant a Secret that contains `tls.key`.

### Tests

`helm-unittest` in the cozy-lib test chart (`make -C
packages/tests/cozy-lib-tests test`) covers: the rendered object is
`Opaque` with `ca.crt` and no `tls.key`/`tls.crt`; the `tenantresource`
label is present; caller labels/annotations merge while the security
label always wins; the helper fails closed on empty `caCert`; and it
refuses a PEM that carries private key material.

### Release note

```release-note
NONE
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added a Helm helper to generate CA-only Kubernetes TLS trust-anchor
secrets, including input validation (rejects private key material,
requires a properly formatted certificate, and ensures required
metadata).

* **Tests**
* Introduced a dedicated test suite covering successful rendering,
metadata and content assertions, tenant label enforcement,
label/annotation merging, and detailed failure cases for invalid inputs
and incorrect arguments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:13:52 +03:00
Aleksei Sviridkin 51c5273d0b feat(platform): ACME wildcard certificate on the default ingress-nginx path (#2988)
## What this PR does

On the default ingress-nginx path (`gateway.enabled=false`) every
published hostname still minted its own per-host ACME certificate via
ingress-shim, even with a DNS-01 solver configured. That hits the Let's
Encrypt rate limit (50 certs per registered domain per week) once a
deployment exceeds ~50 endpoints. The Gateway API path already issues a
single per-apex wildcard in DNS-01 mode; this brings the ingress-nginx
path to parity. It implements the remaining ingress-nginx gap that #2400
was narrowed to in its triage comment (DNS-01 is already multi-provider,
and the Gateway path already issues wildcards).

The new `publishing.certificates.wildcard` toggle is opt-in and OFF by
default. When set to `true` with `solver=dns01` and no operator-provided
wildcard Secret, the platform issues one shared wildcard `Certificate`
for `<root-host>` + `*.<root-host>` and serves the resulting Secret as
the publishing controller's `--default-ssl-certificate`. The system
service Ingresses (dashboard, grafana, keycloak, harbor, …) then stop
requesting a per-host cert.

How it works:

- `core/platform` `apps.yaml` computes the effective wildcard Secret
name and a new `_cluster.wildcard-issue` signal. An operator-provided
`wildcardSecretName` (the BYO path) always wins and never triggers
issuance; HTTP-01 cannot issue wildcards; and when Gateway API is
enabled the TenantGateway controller issues the wildcard instead — so
all three are excluded from auto-issuance.
- `extra/ingress` renders the wildcard `Certificate` only on the
publishing controller (`Release.Namespace == expose-ingress`), because
the Secret must be same-namespace for ingress-nginx to read it. The
Certificate references the DNS-01 `ClusterIssuer` that
`cert-manager-issuers` already renders in `dns01` mode, so no per-tenant
Issuer is minted.

This reuses the existing wildcard-secret consumption path, so no
per-service Ingress template changes were needed — only the issuance
side is new.

Why opt-in (default off): the chosen wildcard Secret name rides the
`_cluster` channel, which every child tenant inherits verbatim, so this
is not root-tenant scoped. A single-label wildcard `*.<root-host>`
covers `<service>.<root-host>` but not a custom service host outside it
(a keycloak `ingress.host`, harbor `host`, or grafana `host` pointed at
another domain) nor a child tenant's nested host
(`<service>.<tenant>.<root-host>`). Enabling issuance makes every such
service drop its per-host ACME cert and fall back to the default
certificate, which does not cover it. Leaving it off by default means a
dns01 cluster is never silently switched on upgrade; an operator who
enables it accepts the same coverage responsibility as the
operator-provided wildcard path, which propagates identically. The
tradeoff is pinned by contract tests (keycloak custom host, bucket
nested child-tenant host). Per-tenant wildcards remain on the Gateway
path and are tracked separately.

Docs: cozystack/website#588

Closes #2400. Part of #2811.

### Screenshots

N/A — no UI changes.

### Release note

```release-note
feat(platform): add opt-in shared wildcard certificate issuance on the default ingress-nginx path via publishing.certificates.wildcard (default false). When enabled with a DNS-01 solver, the platform issues one *.<root-host> wildcard for system services instead of a per-host ACME certificate, avoiding Let's Encrypt rate limits at scale.
```



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added automatic wildcard certificate issuance support for DNS-01 ACME
solver.
* New `certificates.wildcard` configuration option to enable shared
wildcard TLS certificates.
* Ingress rules now properly utilize wildcard certificates when enabled.

* **Tests**
* Added comprehensive test suites validating wildcard certificate
generation and ingress integration across multiple scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:13:48 +03:00
Aleksei Sviridkin ad8367c9b6 chore(nats): bump nats to 1.3.16 (#2976)
## What this PR does

Bumps the nats chart from 1.3.13 to 1.3.16 (app 2.11.8 → 2.11.10), the
latest patch in the 1.3 line, picking up the published security fixes
the issue enumerates (nats-server 2.11.10 bumps `golang.org/x/crypto` to
v0.42.0 and the Go toolchain to 1.24.7) plus upstream bug fixes
(route-reconnect storms, stream interest loss when lowering
max-connections, JetStream meta performance).

Pins the `update` target to `--version 1.3.16` so `make update` stays on
the 1.3 line instead of floating to the 2.x chart restructure. The
cozystack overrides (PVC retention policy, cluster routeURLs domain,
prometheus exporter PodMonitor) stay valid.

Adds helm-unittest coverage (the package shipped none): pins the server
image, the PVC retention policy, and the PodMonitor invariant. `helm
unittest` 3/3 pass.

Verified: `helm template` renders `nats:2.11.10-alpine`, the retention
policy, and the PodMonitor; vendored tree is byte-identical to a fresh
upstream pull.

Closes #2890

### Release note

```release-note
chore(nats): bump nats to 1.3.16 (app 2.11.10)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added configurable Kubernetes `resources` (requests/limits) for the
NATS container and nats-box.

* **Chores**
  * Updated NATS image to `2.11.10-alpine`.
  * Updated config reloader image to `0.20.1`.
  * Updated nats-box image to `0.19.2`.
  * Updated the Helm chart to `1.3.16` (NATS appVersion to `2.11.10`).

* **Tests**
* Added automated Helm chart validation tests, including stricter
rendering checks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:13:43 +03:00
Aleksei Sviridkin 5004af8810 chore(vertical-pod-autoscaler): bump VPA to 11.1.1 (#2975)
## What this PR does

Bumps the vertical-pod-autoscaler chart from 10.0.0 to 11.1.1 (app 1.3.0
→ 1.5.0, latest upstream), moving the VPA components
(admission-controller, recommender, updater) to
`registry.k8s.io/autoscaling/vpa-*:1.5.1` and picking up the published
security fixes the issue enumerates.

The chart-major bump keeps every cozystack override valid: the
recommender's prometheus storage config (`storage=prometheus`,
`prometheus-address`, container labels), `crds.enabled: false`, and the
updater/admissionController resource blocks.

Two Bitnami-adjacent details, both correctly neutralized:

- Upstream 11.0 switched the bundled CRD-install Job image to
`bitnamilegacy/kubectl`. cozystack disables that Job (`crds.enabled:
false`) and overrides `crds.image` to `docker.io/alpine/k8s`, so no
Bitnami image is ever pulled — verified by render.
- The `common` library subchart dependency moved off the sunset Bitnami
repo (`charts.bitnami.com` → `oci://ghcr.io/cowboysysop/charts`), a free
supply-chain improvement.

VPA 1.5 deprecations (humanized memory flag, UpdateMode `Auto`) are not
used by cozystack.

Adds helm-unittest coverage (the package shipped none): pins the
recommender prometheus args, the non-Bitnami `registry.k8s.io` image,
and the `crds.enabled=false` → no CRD-install Job invariant. `helm
unittest` 3/3 pass.

Closes #2882

### Release note

```release-note
chore(vertical-pod-autoscaler): bump VPA to 11.1.1 (app 1.5.0)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added support for `InPlaceOrRecreate` pod update mode.
  * Improved OCI-based Helm install/upgrade documentation and examples.
* **Improvements**
* Updated chart/component versions (including VPA components to 1.5.x
and chart to 11.1.1).
* Hardened security defaults (seccomp RuntimeDefault and container
hardening) and added image integrity checks during upgrades.
* Expanded RBAC permissions for admission controller and event/workload
handling.
* **Chores**
* Updated the shared Helm library version and refreshed chart
tests/invariants.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:13:39 +03:00
Aleksei Sviridkin 713fcdcb32 chore(velero): bump velero to 12.0.3 (#2974)
## What this PR does

Bumps velero from 11.0.0 to 12.0.3 (appVersion 1.17.0 → 1.18.1, latest
upstream), picking up the published security fixes the issue enumerates
across the velero server and its backup plugins.

- Re-vendors the chart via `make update` (now pinned to `--version
12.0.3` for reproducible re-vendoring). The 12.0 major bump's
values-schema changes are backward-compatible (two required fields
relaxed, one optional key added), so all cozystack overrides
(`upgradeCRDs`, `initContainers`, `configuration.*`, `deployNodeAgent`)
stay valid.
- Moves the backup-plugin initContainers to their velero-1.18-aligned
releases: `velero-plugin-for-aws` v1.12.1 → v1.14.1 (the release that
bumps to velero 1.18.1; also corrects a pre-existing plugin/server skew)
and `kubevirt-velero-plugin` v0.8.0 → v0.9.0.
- Adds helm-unittest coverage (the package shipped none): pins the
server + plugin image tags and the `upgradeCRDs: false` → no
upgrade-crds Job invariant, which has silently regressed before.

The 1.18 "PVC selected-node" deprecation needs no action (velero handles
it transparently); CRD changes are additive.

Verified: `helm template` renders all three images; `helm unittest` 3/3
pass (mutation-checked).

**Upgrade note:** Helm v3 does not update CRDs on `helm upgrade`
(upgradeCRDs is disabled). On existing clusters the 1.18 CRDs must be
applied manually (`kubectl apply --filename
packages/system/velero/charts/velero/crds/`).

Closes #2886

### Release note

```release-note
chore(velero): bump velero to 12.0.3 (app 1.18.1) and backup plugins to velero-1.18-compatible releases
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Backup status queue tracking (`queuePosition`) plus new `phase`
states.
* Added `caCertRef` Secret reference for BackupStorageLocation (with
`caCert` marked deprecated).
* Added incremental-bytes reporting (DataUpload, PodVolumeBackup) and
`snapshotSize` for PodVolumeRestore.
* Added `backupSyncPeriod` configuration and `nodeAgent.disableHostPath`
option.
* **Upgrades**
* Updated Velero to app 1.18.1 / chart 12.0.3, including plugin image
tag bumps and updated kubectl image defaults.
  * Added chart/app version labels across key resources.
* **Operational Improvements**
* Improved CRD cleanup/upgrade job execution and tuned the
“VeleroNoNewBackup” alert.
* **Tests**
* Added a `test` target (runs `helm unittest`) and expanded chart
rendering invariants checks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:13:35 +03:00
Aleksei Sviridkin 553c0be708 chore(mongodb): bump psmdb-operator and CR to 1.22.0 (#2968)
## What this PR does

Bumps the Percona Operator for MongoDB stack from 1.21.x to 1.22.0
(latest upstream release), picking up the published security fixes in
the operator image that the issue enumerates.

Two coupled changes:

- `system/mongodb-operator`: re-vendors the upstream psmdb-operator
chart 1.21.2 → 1.22.0 via `make update` (operator image →
`percona/percona-server-mongodb-operator:1.22.0`). The vendored tree is
byte-for-byte identical to a fresh upstream pull.
- `apps/mongodb`: bumps the managed CR `spec.crVersion` 1.21.1 → 1.22.0
so the platform tracks the deployed operator instead of running at the
N-1 skew, plus the matching helm-unittest assertion.

The 1.22.0 CRD diff is additive (native MinIO backup storage, storage
scaling, `hookScript`, `PBMReady` condition, new `metrics.k8s.io` RBAC
that activates under our `watchAllNamespaces: true`). The only schema
removal — the restore-spec `replset` string, renamed upstream to
`replsetRemapping` — is unused by the cozystack mongodb app (restore
template uses `clusterName`/`pitr`/`backupSource` only). Deprecations
(PSMDB 6.0, PMM2, `enableVolumeExpansion`) stay backward-compatible. The
PBM (`2.11.0`) and PMM (`2.44.1`, disabled by default) sidecars stay
compatible with 1.22.0 and are out of scope here.

Verified: `helm unittest packages/apps/mongodb` 94/94 pass; `helm
template` renders the operator with the new image.

**Upgrade note:** Helm v3 does not update CRDs on `helm upgrade`. On
existing clusters the 1.22.0 CRD must be applied manually (`kubectl
apply --server-side -f .../crds/crd.yaml`); the operator pod itself runs
fine against the older CRD until then.

Closes #2888

### Release note

```release-note
chore(mongodb): bump psmdb-operator to 1.22.0 and managed CR to crVersion 1.22.0
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* MongoDB Operator upgraded to version 1.22.0 with enhanced custom
resource definitions supporting backup storage configuration, hook
scripts, and storage autoscaling capabilities
* Added configurable namespace override for flexible operator deployment
  * Extended RBAC permissions for metrics collection

* **Chores**
  * Kubernetes minimum version requirement updated to 1.32+
  * Helm chart version bumped to 1.22.0

* **Documentation**
* Expanded CRD upgrade and installation guidance with multiple upgrade
strategies

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 13:13:31 +03:00