Add metricSource contract (metric alerts phase 2) - #140
Open
acoshift wants to merge 4 commits into
Open
Conversation
Phase 2: scrape sources (own deployment + port + path, no URL field) and AlertTarget.Kind=custom (value/rate). Collector listMetricSources / setCustomUsage types for the in-cluster scrape loop.
The collector caps samples at 100 before ingest, so apiserver cannot infer overflow from list length. Truncated/LastError ride the same RPC so the source row can show a banner and scrape errors.
A failed scrape has no samples, so LastError needs a source id on the request itself.
Without Type on the ingest item, apiserver stored every series as untyped and never took the counter increase path on live scrapes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 2 of metric alerts: the API contract for scraping a project's own Prometheus
/metricsendpoint, charting the series, and alerting on them.metricSource resource
Project-scoped scrape sources addressed by
(project, name), with location in config (same shape asalert).metricSource.set/.get/.list/.delete/.series/.querySetis a full upsert (cache.setstyle): first Set of a name creates, subsequent Sets of the same name replace config. Max 4 sources per project is server-enforced when creating a new name (MetricSourceMaxPerProject);Valid()does not count existing sources.(deployment, port, path)only — no URL field. Path defaults to/metrics, must start with/, and must not contain://or a host. That is the v1 SSRF bound: apiserver resolveshttp://<kubeName>.<ns>:port/pathfor the collector.metricSource.queryreturns[]*DeploymentMetricsLineso Chart.svelte is unchanged. Time range is the waf/cache short windows (1h|6h|12h|1d|7d|30d), not deployment1hagg.Permissions:
metricSource.*/.set/.get/.list/.delete. Series/query are gated bymetricSource.get. Reads are public-bindable (nothing secret).AlertTarget.Kind=custom
Additive on the existing alert contract:
Kindempty or"deployment": existing platform metrics (cpu|memory|requests|egress);Location+Deploymentrequired;Source/Seriesmust be empty.Kind="custom":Source(metricSource name) +Series(exactname{sortedLabels}key);Location/Deploymentmust be empty (location lives on the source). Condition metric isvalue(gauge) orrate(counter per-minute).Existing deployment creates with empty Kind still validate.
Collector RPCs (internal)
collector.listMetricSources {location}→ enabled sources with platform-resolved URL. The request type has no URL field.collector.setCustomUsage {location, list: [{projectID, sourceID, series, value, at}]}— list may be empty.Merge first
Dependents (apiserver, collector, console, mcp, CLI, docs) should wait to re-pin until this PR is merged; do not pin the branch SHA.