Files
shopdb-flask/plugins/endpoints/DELIVERY-TESTING-notes.md
Cam Proudlock 6680c3c5de Merge the wilm delivery work into main
Ben Baker's installed-software collection, software delivery (run_script and
update_app), agentless adoption tool and command-queue hardening, with his
authorship preserved.

Reviewed before promotion. Fixed: the endpoints plugin tests were never collected
by pytest, the SBOM snapshot table's key would exhaust on MySQL, ingest did not
truncate two columns strict MySQL would reject, and update_app's version branch
pinned a digest for a file that route never serves. Agent packaging moved off
require_role('admin') onto a new endpoints.agentpackage permission.

Contract 0.27.0. Full suite 2231, frontend 314.
2026-08-30 19:41:15 -04:00

4.8 KiB

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.