- Home
- Multi-Cloud Networking
- Customer Edge diagnostics
- Reaching a Customer Edge
- Debug API
Debug API
Captured 2026-08-03 from one CE of the rebuilt deployment. sitecli/catalog.json records
the node, build, and 43-command surface; scripts/capture-sitecli.sh --check re-verifies it
against a live CE.
The vpm/debug API runs Site CLI commands on a registered node and returns their
output. Everything below was established against a live node; none of it is
published upstream.
The command catalog is self-describing
Section titled “The command catalog is self-describing”Ask the node what it supports by POSTing to exec-user with the command key
omitted:
curl -sS -X POST \ -H "Authorization: APIToken $XCSH_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"namespace":"system","site":"<site>","node":"<node>"}' \ "$XCSH_API_URL/api/operate/namespaces/system/sites/<site>/vpm/debug/<node>/exec-user" \ | jq -r .output | jq .The response is a JSON object keyed by command name:
{ "crictl-inspect": ["System Troubleshooting", "ExecUser", " container-id"], "diagnosis": ["System Troubleshooting", "ExecUser", "no argument needed", "GLOBAL"], "ip-link-set": ["Network Troubleshooting", "Exec", " (<device>||<group>) (up||down)"]}Each entry is [category, tier, exampleArgument?, scope?], and those fields are
not documentation — they decide how the command must be called.
Three transports, chosen by the catalog entry
Section titled “Three transports, chosen by the catalog entry”| Condition | Method and path | Body | Returns |
|---|---|---|---|
scope is GLOBAL | GET .../vpm/debug/global/<cmd> | none | JSON |
tier is ExecUser | POST .../vpm/debug/<node>/exec-user | command array | text |
tier is Exec | POST .../vpm/debug/<node>/exec | command array | text |
ExecUser — the ordinary tier 33 commands
Section titled “ExecUser — the ordinary tier ”The common case. Pass the command and its arguments as an array, command name first:
curl -sS -X POST \ -H "Authorization: APIToken $XCSH_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"namespace":"system","site":"<site>","node":"<node>","command":["crictl-ps"]}' \ "$XCSH_API_URL/api/operate/namespaces/system/sites/<site>/vpm/debug/<node>/exec-user"{ "return_code": 0, "output": "CONTAINER IMAGE CREATED STATE ..." }Arguments are separate array elements, not a single string:
{ "command": ["journalctl", "-u", "vpm", "-n", "200"] }GLOBAL — site-wide, and a different transport entirely 2 commands
Section titled “GLOBAL — site-wide, and a different transport entirely ”health and diagnosis are the only two. They are GET requests to a global
path, take no arguments, and return structured JSON rather than terminal text.
curl -sS -H "Authorization: APIToken $XCSH_API_TOKEN" \ "$XCSH_API_URL/api/operate/namespaces/system/sites/<site>/vpm/debug/global/health" | jq .Exec — the privileged tier 8 commands
Section titled “Exec — the privileged tier ”A separate endpoint, and the tier is enforced rather than advisory: exec rejects
an ExecUser command with the same command not supported message. Every member
either changes the node or reads a state marker.
On the current build, the tier contains ip-link-set,
systemctl-restart-NetworkManager, systemctl-restart-crio,
systemctl-restart-kubelet, systemctl-start-crio-prune and three
marker-exists-* commands.
Finding the site and node names
Section titled “Finding the site and node names”The node name is the Azure VM name, and list-service is a cheap way to confirm it
alongside the services running on it:
curl -sS -H "Authorization: APIToken $XCSH_API_TOKEN" \ "$XCSH_API_URL/api/operate/namespaces/system/sites/<site>/vpm/debug/global/list-service" \ | jq -r '[.service[].node] | unique'["", "f5-xc-ce-vm-01"]Some services report an empty node name, so an empty string in that list is an artefact of
the response rather than a second node. list-service is also not in the 43-command catalog:
it is a global endpoint the catalog does not advertise, which is why it is documented here
and not in the command reference.
Reproducing this repository’s captures
Section titled “Reproducing this repository’s captures”Every command page embeds output captured by scripts/capture-sitecli.sh, which
implements all three rules above.
-
Point it at a tenant. It reads
XCSH_API_URLandXCSH_API_TOKEN, or falls back to the activexcshcontext. -
Refresh the catalog and confirm the node has not changed underneath the documentation:
Terminal window bash scripts/capture-sitecli.sh --checkThis compares the committed catalog and the software build only. It reports a build change separately from added or removed commands.
-
Re-capture when you want fresh evidence:
Terminal window bash scripts/capture-sitecli.sh