Commit Graph
40 Commits
Author SHA1 Message Date
mrhid6 8908b435a0 docs(monitors): document heartbeat and metric monitors; add heartbeat e2e 2026-09-17 09:16:53 +00:00
mrhid6 069e7e7c61 fix(api): declare MFA routes session-only so the server boots
Chart Release / chart (push) Successful in 36s
Server Deploy / deploy (push) Successful in 3m0s
The MFA routes were missing from routeScopes and serverScopedRoutes, and both
boot assertions refused to start the server. They are deliberately not
reachable by API tokens, so they go in a new sessionOnlyRoutes set rather than
receiving a scope, and are declared exempt from server scoping.

Adds a test that registers the real routes and runs both boot assertions, so
an undeclared route fails CI instead of production startup.
2026-09-16 14:40:29 +00:00
mrhid6 142b99e408 test(mfa): end-to-end coverage, OpenAPI and documentation 2026-09-16 14:18:39 +00:00
mrhid6 3f2d20868e fix(patching): final review fixes
Chart Release / chart (push) Successful in 19s
Server Deploy / deploy (push) Successful in 6m12s
- no dispatch in the last 15 minutes of a window; no-result timeout from dispatch time
- per-server output moves to patch_run_outputs (16MB document limit)
- reboot proven by a changed boot time; RebootTimeout 45m, ResultGrace 20m
- window update and delete are server-scoped against the policies using them
- scheduler puts the claim back on an error after it, so the next tick retries
- cancelled runs with failures alert; MCP apply_updates audits per server
- apply-updates 503 body documented; openapi regenerated
- web: cleared numeric fields no longer save as 0; Run now asks for confirmation
2026-09-15 13:49:28 +00:00
mrhid6 b5bbf28c63 feat: patching REST API, patching scope, run IDs from apply-updates and MCP 2026-09-15 09:31:51 +00:00
mrhid6 5ca705c88c feat: login page says a locked instance is suspended instead of drawing the form
Chart Release / chart (push) Successful in 20s
Server Deploy / deploy (push) Successful in 4m4s
2026-09-11 09:05:44 +00:00
mrhid6 d2672fc022 docs: HQ dispute lock and purge contract 2026-09-10 13:25:47 +00:00
mrhid6 6ee203f5e9 chore: replace em dashes with hyphens, add no-em-dash rule to CLAUDE.md
Chart Release / chart (push) Successful in 20s
Server Deploy / deploy (push) Failing after 1m52s
2026-09-10 09:18:55 +00:00
mrhid6 b36a696d0e feat: Added nginx container to docker compose file
Server Deploy / deploy (push) Successful in 9s
Chart Release / chart (push) Successful in 10s
2026-09-10 08:43:25 +00:00
mrhid6 e0cc3988fc refactor: move vantagectl to vantage-ctl
vantagectl/ becomes the root of gitea.hostxtra.co.uk/vantage/vantage-ctl.
The command keeps the name vantagectl; only the repository and the image
path change, to vantage/vantage-ctl.

chart-release.yml's render checks are repointed at the new image. The
chart itself has no default backup.image and fails loudly without one, so
an existing cluster keeps working until someone changes the value.

go.work stays, now with a single use ./server entry: without it a go.work
further up the developer's filesystem is picked up instead.
2026-09-08 09:07:14 +00:00
mrhid6 44d9036440 refactor: move the agent and its installer to vantage-agent
agent/ becomes the root of gitea.hostxtra.co.uk/vantage/vantage-agent,
with installer/ alongside it, and agent-release.yml goes with them.

Releases now come from that repository, so the six places this server
generates or reads a release URL are repointed: both install scripts,
both update scripts, and the latest-version lookup in dispatch.go. The
agent/v* tag prefix is unchanged — those scripts grep for it.

Agents built before this move have the old mrhid6/vantage path compiled
into their self-update and will 404 on the push-button update. The
remedy is the /update one-liner, which this server generates and which
therefore has to ship first.
2026-09-08 09:00:22 +00:00
mrhid6 1c6d9e8495 refactor: move proto/ to vantage-shared
vantage.proto documents the hand-written types in shared/grpc/pb, and
nothing compiles it. Keeping it in a different repository from the Go
types it describes meant the one rule holding them together — add the
message to both in the same commit — could not be followed at all.

server's rebuild trigger loses proto/, which it only carried as
insurance against exactly that split.
2026-09-08 08:44:47 +00:00
mrhid6 f9dec9b230 refactor: move the public host out to vantage-site and vantage-docs
site/ and sitesvc/ become web/ and server/ in vantage-site; docsite/
becomes the root of vantage-docs. Their images move with them, to
vantage/vantage-site/{web,server} and vantage/vantage-docs.

Nothing here imported any of them, and sitesvc turned out to read no
database at all, so both cuts are clean. docker-compose.site.yml is
deleted rather than emptied: every service it held now ships with the
repository that builds it, and deploy/docker/docker-compose.yml is once
again exactly a self-hosted install.

Corrects four comments that named sitesvc for work it no longer does.
2026-09-08 08:41:11 +00:00
mrhid6 872699c38c refactor: move Vantage HQ out to the vantage-admin repository
admin/ and adminsite/ are extracted with their history to
gitea.hostxtra.co.uk/vantage/vantage-admin, where they are named server/
and web/ for what they are rather than for the services they run. Their
images move with them, to vantage/vantage-admin/{server,web}.

Nothing here imported them, so the cut is clean: the only coupling was
always at runtime, through admin writing into the control plane's
database. The parts of that contract this side enforces are unchanged and
still documented here — hq-sourced users, POST /license answering 409
cloud_managed, and FREE_INSTANCE_REAP_AFTER needing to match.

LICENSE_SIGNING_KEY now appears in no compose file in this repository.
Keeping it out used to be a rule someone had to remember; it is the
repository boundary now.

docker-compose.site.yml loses both services and gains a note on how the
host composes the three files together.
2026-09-08 08:13:55 +00:00
mrhid6 ee1f9f3b32 refactor: consume vantage-shared as an external private module
shared/ is extracted to gitea.hostxtra.co.uk/vantage/vantage-shared and
pinned at v0.1.0 by server, agent, admin, sitesvc and vantagectl. The
replace directives and the ./shared entry in go.work are gone.

Every Go build now needs a credential for the private module: CI writes a
netrc per job from REGISTRY_USER + RELEASE_TOKEN and sets GOPRIVATE, and
the four Go Dockerfiles take it as a BuildKit secret rather than a build
arg, which would survive in the builder layer's history. RELEASE_TOKEN
needs read access to the vantage org.

admin, sitesvc and vantagectl now build from their own directory; only
server still needs the repository root, for default_steps/. The rebuild
triggers in server-deploy.yml lose their shared/ patterns, since a
service now moves when its own go.mod pin does.
2026-09-08 07:42:58 +00:00
mrhid6 189a8fa963 feat: Move grpc pbs to shared 2026-09-07 15:50:25 +00:00
mrhid6 7b13944c24 fix: Build the vantagectl image on its release tag, not on every push to main
vantagectl is a released tool, not a running service. An operator restoring a
database should be able to name the version they ran, and ":latest, rebuilt
whenever main moved" cannot be named after the fact.

The image now builds in vantagectl-release.yml on a vantagectl/v* tag, tagged
with that version as well as latest, with VERSION passed through so the binary
inside reports the tag rather than "dev". server-deploy.yml no longer builds
it and is back to seven images.

The cost is that a shared/ fix reaches the image only at the next release
rather than the next push to main. That is the intended trade and is written
down in CLAUDE.md next to the trigger table.
2026-09-07 15:11:39 +00:00
mrhid6 be299845ca fix: document inspect and --confirm-db's actual behaviour 2026-09-07 14:45:37 +00:00
mrhid6 89cc524f3f docs: Document backup and restore
The page leads with KEY_ENCRYPTION_KEY rather than mentioning it in a
note, because holding a good database dump and no key is the way this goes
wrong.
2026-09-07 14:29:03 +00:00
mrhid6 c440b59b93 feat: Updated affected components on status page incidents 2026-08-25 14:56:50 +00:00
mrhid6 3e4865884c feat: Updated plans and catalogue pages 2026-08-25 14:35:47 +00:00
mrhid6 7a0a1953f6 fix: Fixed api url on web 2026-08-25 13:53:59 +00:00
mrhid6 28b813ba64 feat: sell status pages as a per-instance licence feature 2026-08-25 09:25:05 +00:00
mrhid6 68160dc681 docs: correct the status page URL for self-hosted, trim to what ships
- The status page URL was given only as `<instance>.vantage.<tld>`, which a
  self-hosted install does not serve. Both deployments are now described.
- The banner is documented as one notice: the editor exposes no level picker
  and the view renders every level identically.
- `pending` added to the component states, which a monitor with no result yet
  renders.
- Delete page documented alongside un-publish.
- `TRUSTED_PROXIES` names the LAN case: with the RFC1918 default, a client on a
  private range reaching the server directly is itself trusted and can spoof
  `X-Forwarded-For` — and now `X-Forwarded-Host`. Narrow it to the proxy.
- CLAUDE.md: scopes are nine resources, not eight; `status-pages` added to the
  REST route table; the host-resolution rules recorded under Status pages.
2026-08-25 09:05:06 +00:00
mrhid6 72c9492223 docs: status pages 2026-08-25 08:44:38 +00:00
mrhid6 a0fbf5b9ba fix: Word and colour Windows workloads correctly across the UI 2026-08-13 12:57:37 +00:00
mrhid6 ddf0814803 docs: Fix Windows package-inventory and poll-loop claims in CLAUDE.md 2026-08-13 12:28:51 +00:00
mrhid6 2bc15648b7 docs: Describe the Windows agent's update and workload support 2026-08-13 12:23:34 +00:00
mrhid6 7e767ecb4f fix: Move the API keys page off the /api prefix
/api-keys shares a raw string prefix with /api, and the proxies in front
of this app do not all match by path segment. Nginx Proxy Manager routes
/api straight to the Go server with a prefix location, so /api-keys never
reached Next at all — it reached a control plane with no such route and
came back as a JSON 404. Traefik's PathPrefix has the same shape of
matcher, which puts the Helm ingress at risk whenever ingress.api.enabled
is on.

The page is /tokens now, which cannot collide with anything, and which
matches the /api/tokens the REST API already publishes. The sidebar still
says API Keys — the label is for the reader, the path is for the router.

A permanent redirect covers anyone who bookmarked the old path today.
Fixing the proxy config instead would have left the trap set for the next
deployment, and for whatever sits in front of it.
2026-08-13 09:26:34 +00:00
mrhid6 689d0e1d5b feat: Give API keys their own page and group the sidebar
The token management card sat on /settings, which is owner|admin
throughout, so it hid a capability every member already had: the API has
never required a role to mint or revoke your own key. It is now the
/api-keys page, reachable at every role, with the instance-wide lifetime
cap left behind on /settings because that is policy rather than one
person's credentials — and that split is what lets the page be ungated.

The sidebar gains groups: Fleet, Access, Automation, Instance, each with a
small-caps heading and a rule above it. Grouping is by what the operator
is doing rather than by which service answers, so SSH keys, secrets and
API keys sit together as credentials. A group whose every item is
admin-only disappears whole for a member; a labelled section with nothing
under it reads as a failure rather than a restriction.

The UI says keys while the collection, prefix and routes still say tokens.
Renaming a published endpoint to match a nav label would break every
script already written against it.
2026-08-13 08:54:42 +00:00
mrhid6 f6988b0f1e docs: Correct API token access-control claim in CLAUDE.md 2026-08-13 08:12:48 +00:00
mrhid6 0784ef3719 docs: Document API tokens and the OpenAPI reference 2026-08-13 08:04:09 +00:00
mrhid6 f534b74066 docs: Document instance rename in HQ 2026-08-12 10:52:43 +00:00
mrhid6 a228ab24a0 feat: Changes to self hosted purchase 2026-08-11 09:30:19 +01:00
mrhid6 4ff8fc8d51 docs: document the workload registry 2026-08-07 09:09:18 +01:00
mrhid6 da6d64f95c fix: give the scratch server image a /tmp for the vulnerability database
The runtime stage is FROM scratch, which has no /tmp, so vulnsched died at
startup with "temp dir: stat /tmp: no such file or directory" and no scan
ever ran. Nothing in the server wrote to a temporary directory before the
trivy-db puller, which is why this only appeared now.

scratch cannot mkdir its own, so the directory is staged in the builder at
1777 and copied in. Also corrects CLAUDE.md, which described this image as
Alpine; the time/tzdata import it justifies is if anything more load-bearing
on scratch.
2026-08-06 15:46:30 +01:00
mrhid6 f60c509b47 feat: vuln_scanning entitlement and documentation
Adds license.FeatureVulnScanning as the one name for the feature and a
catalogue row per deployment/tier, following console and oidc: features
are opt-in per customer, so no plan bundles it.

Documents the subsystem in CLAUDE.md, including that ScopedCollections is
the canonical registry instance deletion derives from — there is no
separate deletion list, which the plan had wrong.
2026-08-06 14:44:11 +01:00
mrhid6 50a9ac5fdc fix: count tag-matched servers in the workflows list 2026-08-04 17:28:01 +01:00
mrhid6 3a77fc2abd feat: edit target servers and tags together in the workflow modal 2026-08-04 17:21:12 +01:00
mrhid6 d9184312aa fix: schedule card placement, preview state, and scheduled-workflow docs 2026-08-04 17:08:11 +01:00