Skip to content

serve

upgradescope serve

Run the upgradescope server: snapshot ingest, REST API, history, notifications

Synopsis

Run the upgradescope server. It accepts snapshots that agents push, evaluates them against every target, keeps the history, serves the REST API and the dashboard at /, and sends Slack or webhook notifications when a cluster's readiness changes: a new blocker, all blockers resolved, or an add-on entering its end-of-life window. Each pass is compared with the target's last baseline, an evaluation that is decided or unknown only because the target is past the knowledge base's horizon. A target's first baseline is silent (after an upgrade, the previous default target's is used), and a pass that is unknown because a collector failed sends nothing and is no baseline (docs/operations.md, Notifications).

It listens on loopback by default. On any other address, the read API needs a credential: --read-token (fleet-wide), read tokens minted with 'upgradescope tokens create --read --teams ...' (each scoped to teams, or '*' for the fleet), or an authenticating proxy's team header (--trust-team-header with --trusted-proxy-cidr); or an explicit --allow-anonymous-read.

Whether a read token has been minted lives in the database, so a lost, emptied or restored database reopens a read API that relied on minted tokens (and --allow-anonymous-read allows it). --require-read-credential closes it for good: reads are never open, and return 401 until a credential exists. While the read API is open, a request that presents a bearer nothing knows gets 401, and an anonymous request must name a host the server answers for (--allowed-host), on any listen address.

upgradescope serve [flags]

Examples

  # Local dashboard at http://127.0.0.1:8080/, SQLite in ./upgradescope.db
  upgradescope serve

  # Fleet server: all interfaces, Postgres, tokens from mounted Secrets
  upgradescope serve --listen :8080 \
    --db-url-file /secrets/db-url --read-token-file /secrets/read-token \
    --targets 1.37,1.38

Options

      --admin-token string             bearer token for cluster administration: DELETE and PATCH (rename) /api/v1/clusters/{id}, 'upgradescope clusters delete|rename --server-url'; it also reads (empty = administration refused) (visible in process listings: prefer $UPGRADESCOPE_ADMIN_TOKEN or --admin-token-file)
      --admin-token-file string        read --admin-token from this file, e.g. a mounted Secret (surrounding whitespace is trimmed); the file is re-read when it changes (checked at most every 5s, when it is next needed), so a rotated Secret needs no restart. A value from the flag or the environment is read once
      --allow-anonymous-read           serve the read API and /api/v1/gate without a read token on a non-loopback --listen address (it is open only while no read credential exists: --read-token, a read token minted in the database, or a trusted team header; a lost or restored database reopens it, and a request that presents a bearer nothing knows gets 401); anonymous reads must name a host the server answers for (see --allowed-host); excludes --require-read-credential
      --allowed-host strings           a host name (or IP) requests may name in their Host header, any port, repeatable or comma separated (default $UPGRADESCOPE_ALLOWED_HOSTS): on a loopback --listen, with --trust-team-header, or for an anonymous request while the read API is open (any --listen address), any other Host than localhost, a loopback address, the --listen host (not 0.0.0.0 or ::) or the address the request arrived on gets 421, which stops DNS-rebinding pages; name the Service, Ingress or proxy host the server is reached under
      --db string                      path to the SQLite database (parent directory is created) (default "upgradescope.db")
      --db-url string                  Postgres URL (postgres://user:pass@host:5432/db); mutually exclusive with --db (visible in process listings: prefer $UPGRADESCOPE_DB_URL or --db-url-file)
      --db-url-file string             read --db-url from this file, e.g. a mounted Secret (surrounding whitespace is trimmed)
  -h, --help                           help for serve
      --ingest-token string            optional shared bearer token that may push snapshots as ANY cluster; omit it to accept only per-cluster tokens from 'upgradescope tokens create' (serve warns at startup, not later, when both are in use) (visible in process listings: prefer $UPGRADESCOPE_INGEST_TOKEN or --ingest-token-file)
      --ingest-token-file string       read --ingest-token from this file, e.g. a mounted Secret (surrounding whitespace is trimmed); the file is re-read when it changes (checked at most every 5s, when it is next needed), so a rotated Secret needs no restart. A value from the flag or the environment is read once
      --listen string                  address to listen on (loopback by default; use :8080 for all interfaces) (default "127.0.0.1:8080")
      --max-gate-bytes int             largest accepted /api/v1/gate manifest stream, in bytes; the body must arrive within the 60s read timeout or the request gets 408, and a stream of too many YAML nodes gets 413 whatever its size (the 400k-node budget is about 4.4 MiB of typical kubectl YAML, so it, not this cap, limits a realistic stream) (default 10485760)
      --max-snapshot-bytes int         largest accepted snapshot push body, in bytes (also applied after gzip decompression); the body must arrive within the 60s read timeout (~350 KiB/s at the 20 MiB default) or the push gets 408, and a push that decodes to too many JSON values gets 413 whatever its size; it also caps every report the server evaluates, stores or exports (a push whose report would be larger gets 413) (default 20971520)
      --optional-secret-file strings   names of --*-file flags (ingest-token, slack-webhook, webhook, webhook-secret) whose file may be missing at start, as a key absent from a Secret you manage is: the secret is then unset; a token file that appears later is picked up, and one removed later stops that token working. A file that exists is read as usual
      --read-token string              bearer token for the read API and /api/v1/gate (empty = OPEN read access unless a read token is minted in the database; refused on non-loopback --listen without --allow-anonymous-read; --require-read-credential keeps it closed whatever the database holds) (visible in process listings: prefer $UPGRADESCOPE_READ_TOKEN or --read-token-file)
      --read-token-file string         read --read-token from this file, e.g. a mounted Secret (surrounding whitespace is trimmed); the file is re-read when it changes (checked at most every 5s, when it is next needed), so a rotated Secret needs no restart. A value from the flag or the environment is read once
      --registry-dir string            extra add-on registry entries: one <id>.yaml file or a directory of them, in the schema of registry/CONTRIBUTING.md and validated like the embedded entries; an entry with an embedded id replaces it
      --require-read-credential        never open the read API: a read with no credential, or with a bearer nothing knows, gets 401 even when the database holds no read token (a lost or restored database cannot reopen it); serve warns at startup while no credential exists yet, and mint the first with: upgradescope tokens create --read --teams '*' (same --db or --db-url); or set --read-token; excludes --allow-anonymous-read
      --retention string               prune snapshots and evaluations older than this, in days (90d) or a Go duration (2160h), at startup and daily; each cluster's latest snapshot and its evaluations are always kept; 0 keeps everything (default "90d")
      --slack-webhook string           Slack incoming-webhook URL for delta notifications (visible in process listings: prefer $UPGRADESCOPE_SLACK_WEBHOOK or --slack-webhook-file)
      --slack-webhook-file string      read --slack-webhook from this file, e.g. a mounted Secret (surrounding whitespace is trimmed); the file is re-read when it changes (checked at most every 5s, when it is next needed), so a rotated Secret needs no restart. A value from the flag or the environment is read once
      --stale-after duration           mark a cluster stale (API, dashboard data, /metrics) when its agent has not pushed for this long; agents push at least about every 70m by default (default 2h0m0s)
      --targets strings                extra target versions evaluated on every snapshot, CSV or repeated, e.g. 1.37,1.38; at most 4 distinct minors
      --team-map string                YAML file of {pattern, team} namespace globs overriding team labels (first match wins)
      --tls-cert-file string           PEM certificate (chain) to serve HTTPS directly, TLS 1.2 minimum; requires --tls-key-file; a new handshake re-reads the pair when either file changed (checked at most once a second), so a renewal needs no restart
      --tls-key-file string            PEM private key for --tls-cert-file
      --trust-team-header string       DANGEROUS unless the proxy strips client-supplied copies: scope a read from a --trusted-proxy-cidr peer to the teams this request header lists, comma separated and each percent-encoded where it must be (an authenticating proxy's group header, e.g. X-Forwarded-Groups; never the whole fleet, '*' included); needs --trusted-proxy-cidr
      --trusted-proxy-cidr strings     with --trust-team-header: the source CIDRs (the TCP peer, never X-Forwarded-For) of the proxy that sets that header, repeatable or comma separated, e.g. 10.42.0.0/16; a set of ranges that together hold every address of IPv4 or of IPv6 (0.0.0.0/0, or 0.0.0.0/1 with 128.0.0.0/1) is refused, but keeping the ranges to the proxy and nothing else is your job
      --webhook string                 generic webhook URL: POSTed one versioned JSON notification per cluster and evaluation pass (schema in api/webhook.schema.json) (visible in process listings: prefer $UPGRADESCOPE_WEBHOOK_URL or --webhook-file)
      --webhook-file string            read --webhook from this file, e.g. a mounted Secret (surrounding whitespace is trimmed); the file is re-read when it changes (checked at most every 5s, when it is next needed), so a rotated Secret needs no restart. A value from the flag or the environment is read once
      --webhook-secret string          sign generic webhook requests: X-Upgradescope-Signature: sha256=<hex HMAC-SHA256 of the body with this key> (visible in process listings: prefer $UPGRADESCOPE_WEBHOOK_SECRET or --webhook-secret-file)
      --webhook-secret-file string     read --webhook-secret from this file, e.g. a mounted Secret (surrounding whitespace is trimmed); the file is re-read when it changes (checked at most every 5s, when it is next needed), so a rotated Secret needs no restart. A value from the flag or the environment is read once

SEE ALSO

  • upgradescope - Continuous Kubernetes upgrade-readiness scanner