Files
shopdb-flask/plugins/endpoints/DELIVERY-TESTING-notes.md
benjamin.baker 4590156f30 Add endpoint software delivery: run_script and update_app push
Adds the two delivery actions to the endpoints command allowlist, each gated on a new endpoints.deploy permission ON TOP OF endpoints.command so pushing software is a heavier grant than a routine toggle. Enqueue validates update_app appversionid ownership and installer presence before queueing. New collector-authenticated download routes let the agent fetch installer packages and script bodies by digest rather than pre-staging them or sending bodies over the command wire. Wires the scriptsApi client, the siteagent generator routes, and a temporary dev-only Delivery test bench (view/route/nav) for exercising the path while the production UI is built.
2026-08-30 15:21:10 -04:00

113 lines
4.8 KiB
Markdown

# Delivery testing notes (update_app + run_script)
Temporary field notes for exercising the endpoint delivery path end to end and
for handing the UI work to Cameron. ASCII only, no em-dashes, no emojis, per
repo style. Remove the dev test bench (view, route, nav entry) once the
production delivery UI lands.
## What exists today (the contract Cameron builds against)
Server allowlist (`plugins/endpoints/commands.py`):
- `run_script` - targetkind `script`. `target` is a script NAME the agent
already holds in its local `scriptpaths` allowlist. No body or path crosses
the wire.
- `update_app` - targetkind `app`. `target` is an `appversionid` that resolves
to a ShopDB-hosted installer package. The server pins the package by SHA-256
and passes this version's `silentargs`.
Both actions require `endpoints.deploy` ON TOP OF `endpoints.command`. Queueing
one is the actual authority (audited with the requesting user). The agent claims
it with its collector credential.
Enqueue call (same route as every other endpoint command):
```
POST /api/endpoints/<assetid>/commands
{ "action": "run_script", "target": "remove-network-drives" }
{ "action": "update_app", "target": "<appversionid>" }
```
Rules the UI must respect:
- At most one pending/running command per endpoint. A second enqueue returns
409 (treat as "already in flight", not a failure).
- `update_app` is validated at enqueue: an appversionid with no installer
package or unknown id is rejected 400 before it is queued.
- A version with no `sha256` has no uploaded package yet. Do not offer it for
`update_app`; the agent's integrity check will fail closed.
Read the result back:
```
GET /api/endpoints/<assetid>/commands
```
Each row carries `status` (pending/running/succeeded/failed), `resultmessage`
(short summary) and `resultjson` (structured detail: for run_script the exit
code and script path; for update_app the installer path, exit code and digest
check).
Agent-facing package download (collector-authenticated, not user JWT):
```
GET /api/endpoints/apppackage/<appversionid> (X-API-Key collector token)
```
## The dev test bench
Route: `/endpoints/delivery-test` (sidebar "Delivery test bench", gated on
`endpoints.deploy`). It is deliberately minimal: pick an endpoint, push a script
by name or push an app version, then watch the command log pane. There is no
script-library component yet, so `run_script` takes a free-text name; the agent
runs it only if that name is in its `scriptpaths`.
## Preparing the test endpoint
1. Copy the dev build to the test box:
- `agent\dev-bin\agent\shopdbagent.exe`
- `agent\dev-bin\agent\appsettings.json`
Stage them the same way the site installer does (service exe + appsettings).
2. Provision the collector credential and base URL. Per repo policy these are
NOT in appsettings.json; set the registry values under
`HKLM\SOFTWARE\GE\ShopDB` (`CollectorKey`, `BaseUrl`). The shipped
appsettings has `baseurl` empty and `apikey` = REPLACE_WITH_COLLECTOR_KEY so
the agent fails closed until provisioned.
3. Stage the sample script where appsettings points:
`C:\ProgramData\ShopDB\EndpointAgent\scripts\remove-network-drives.ps1`
(source: `agent\dev-bin\scripts\remove-network-drives.ps1`). The
`scriptpaths` entry in appsettings.json maps the name `remove-network-drives`
to that path.
4. For an `update_app` test, create the application in the Applications module,
upload its installer package (this stamps the version's `sha256`), and note
the version's `appversionid`.
## Collecting logs
Endpoint side (the agent):
- Rolling diagnostics log: `%ProgramData%\ShopDB\EndpointAgent\logs`
(override with `logpath` in appsettings). This is where run_script and
update_app record what they resolved, the digest check, and the installer or
script exit code.
- Windows Event Log source `ShopDB Endpoint Agent` for service faults.
Web UI / ShopDB side:
- The command log pane on the bench (or `GET /api/endpoints/<assetid>/commands`)
shows `status`, `resultmessage` and `resultjson` reported by the agent.
- Ingest observability: unknown/unpersisted telemetry keys are logged by the
endpoints plugin on the API container, so incoming agent data is visible in
the app logs even before UI persistence catches up.
- Audit log records each enqueue (`created EndpointCommand`, action + target +
asset) with the requesting user.
## Notes to capture during testing (for Cameron)
- Round-trip latency from enqueue to a terminal status, at the agent cadence.
- Whether `resultmessage` alone is enough for the operator, or the UI needs to
surface `resultjson` (exit codes, digest mismatches).
- How a 409 (already in flight) should read in the real UI.
- What a failed digest check or non-zero installer exit looks like end to end,
so the production UI can present it clearly.