Skip to content

feat(workloadmonitor): bucket metrics endpoint override (#3443) [backport release-1.6] - #3558

Merged
myasnikovdaniil merged 1 commit into
release-1.6from
backport-3443-to-release-1.6
Sep 3, 2026
Merged

myasnikovdaniil merged 1 commit into
release-1.6from
backport-3443-to-release-1.6

Conversation

@IvanHunters

Copy link
Copy Markdown
Collaborator

What this PR does

Hand-backport of #3443 to release-1.6. The change merged to main on 2026-07-24, after v1.6.0 was cut, so it never reached any 1.6 patch and is currently slated to wait for 1.7. This lands it in 1.6.2.

The cozystack-controller meters S3 bucket sizes for billing by querying SeaweedFS metrics from a VictoriaMetrics vmselect it discovers via the namespace.cozystack.io/monitoring label on the tenant namespace. That discovery assumes the monitoring stack scraping SeaweedFS runs in the same cluster. Some deployments host SeaweedFS (API and metrics both) in a separate cluster, where discovery can never produce a reachable endpoint. This adds a single controller flag, --seaweedfs-metrics-endpoint, exposed as the chart value cozystackController.seaweedfsMetricsEndpoint, to point bucket-size metrics at a remote Prometheus-compatible query API. Empty keeps the existing label-based discovery, so behaviour is unchanged by default.

Backport adaptations

Clean cherry-pick of 95e4faf68; no adaptations required. go build ./cmd/... and the full internal/controller test suite pass.

Screenshots

Not applicable — no UI change.

Downstream repositories

  • No downstream repository is affected by this change

Release note

feat(workloadmonitor): add --seaweedfs-metrics-endpoint to fetch S3 bucket size metrics from a remote Prometheus-compatible endpoint, for deployments where SeaweedFS and its monitoring stack run in a separate cluster

The controller discovers where to query SeaweedFS bucket size metrics
via the namespace.cozystack.io/monitoring label, which assumes the
monitoring stack that scrapes SeaweedFS runs in the same cluster. Some
deployments host SeaweedFS and its metrics in a separate cluster, so
add a --seaweedfs-metrics-endpoint flag to cozystack-controller (and a
matching cozystackController.seaweedfsMetricsEndpoint chart value): an
explicit base URL of a Prometheus-compatible query API, with scheme,
host, optional port and path prefix; /api/v1/query is appended. Basic
auth may be embedded as URL userinfo. The flag is validated and
normalized at startup, so a malformed URL fails the rollout rather
than the queries. Empty keeps label-based discovery unchanged.

Bucket sizes feed billing, so metrics failures no longer collapse to
"no size": previously any query failure yielded an empty result map
and the reconciler overwrote Workload resources with it, silently
wiping the recorded sizes. The reconciler now retains the last known
s3-storage-bytes and s3-physical-storage-bytes values, emits a
BucketMetricsUnavailable warning event on the WorkloadMonitor, and
returns the error from Reconcile so it lands in the reconcile error
metrics.

Assisted-By: Claude <[email protected]>
Signed-off-by: Timofei Larkin <[email protected]>
(cherry picked from commit 95e4faf)
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: df248ce1-bac9-445a-a820-191e584307fa

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added area/monitoring Issues or PRs related to the monitoring stack (vlogs, vmstack, grafana, workloadmonitor) kind/feature Categorizes issue or PR as related to a new feature labels Aug 5, 2026

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.

LGTM

Faithful backport. I diffed the patch of this branch's single commit against 95e4faf68 on main: they are byte-identical across all five files, modulo blob hashes, hunk offsets, and one context line (the pinned controller image, v1.6.1 here against v1.6.0 there, because this branch is further along). The "clean cherry-pick, no adaptations" claim in the description holds. The flag that forced a resolution on the 1.5 backport, --tenant-quota-buffer-percent, is present on release-1.6, which is why nothing conflicted here.

Applicability to the target branch checks out on every surface the change leans on. mgr.GetEventRecorderFor and k8s.io/client-go/tools/record are available, and the build is green. The new +kubebuilder:rbac marker for events is worth checking by hand rather than trusting: hack/update-codegen.sh does invoke controller-gen rbac:roleName=manager-role, but it points it at ./api/v1alpha1/..., ./api/backups/... and ./api/gateway/..., none of which hold a single +kubebuilder:rbac marker, while all 35 of them live under internal/, so the generator reads nothing, writes nothing, and make generate stays clean no matter what a marker says. The chart's ClusterRole is maintained by hand instead. Here the grant does exist in this branch's packages/system/cozystack-controller/templates/rbac.yaml, added earlier by the tenant quota work, so the warning event is genuinely creatable, but that is a coincidence rather than something the marker arranged. Worth a separate issue, and out of scope for a backport. Workload carries no status subresource, so the Update inside CreateOrUpdate does persist the retained status.resources: the retention logic works against a live API server, not only against the fake client in the tests. The new value is reachable in practice through Package.spec.components[].values, so the flag is not a knob nobody can turn.

Ran locally against the branch: go build ./... green, go test ./internal/controller/... green across all packages, helm lint clean, helm template renders --seaweedfs-metrics-endpoint only when the value is set and omits it by default, and make generate produces no drift. I mutation-checked the two behaviours the change is really about. Deleting the loop that seeds resources from the recorded sizes turns both retention tests red on exactly their retention assertions, and dropping the return ctrl.Result{}, bucketMetricsErr turns the query-failure test red on exactly its "expected Reconcile to return an error" assertion. The tests are not paper.

Four non-blocking notes, all inherited verbatim from the original, and none of them things to fix here, since that would break parity. Basic auth embedded as URL userinfo ends up verbatim in the Deployment args, readable through kubectl get deploy -o yaml, the container command line, and the Helm release secret; if that matters for a deployment, the fix belongs on main first. When a namespace carries no namespace.cozystack.io/monitoring label at all, resolvePrometheusURL returns an empty string and queryAllBucketMetrics returns an empty map with a nil error, so retention kicks in with no event, no log line, and no returned error: that is the one path where recorded sizes freeze silently, where they used to be zeroed. The BucketMetricsUnavailable event itself has no coverage, because every fixture leaves Recorder nil and only the nil branch ever runs, which record.NewFakeRecorder would close in a few lines. The chart already has a helm-unittest harness but no case for the new conditional arg.

One question for whoever owns the 1.6 line, not a code objection. Every one of the 29 commits on release-1.6 since v1.6.0 is a fix, chore, ci, docs, or test change, so this would be the first feat on the 1.6 patch series. The commit bundles two things: a genuine data-loss fix (a metrics failure used to overwrite recorded bucket sizes with nothing, which billing reads as an empty bucket) and a new administrator flag. Splitting them would break parity with main, so it lands whole or not at all, and that is a release-management call rather than a review one.

E2E is red on chainsaw/kubernetes-previous and chainsaw/kubernetes-latest, both tenant Kubernetes cluster provisioning. I could not find a causal path from this diff: the new argument renders only when the value is non-empty and it is empty by default, and the changed Go path only executes for WorkloadMonitors that own BucketClaims, which those tests never create. The bucket tests in the same run passed. The parallel 1.5 backport, carrying the same change, fails at a different phase entirely, which also points away from the shared diff. It still needs a green run before merge.

@myasnikovdaniil
myasnikovdaniil merged commit c4440f2 into release-1.6 Sep 3, 2026
39 of 40 checks passed
@myasnikovdaniil
myasnikovdaniil deleted the backport-3443-to-release-1.6 branch September 3, 2026 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/monitoring Issues or PRs related to the monitoring stack (vlogs, vmstack, grafana, workloadmonitor) kind/feature Categorizes issue or PR as related to a new feature size/XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants