Synchronize CLI documentation with management command parity
This commit is contained in:
@@ -22,13 +22,13 @@ Every command requires a connection to a running Central node. The management UR
|
||||
scadabridge --url http://central-host:5000 <command>
|
||||
```
|
||||
|
||||
**Docker:** With the Docker setup, the Central UI (and management API) is available at `http://localhost:9001`:
|
||||
**Docker:** Use Traefik at `http://localhost:9000` to reach the active central node:
|
||||
|
||||
```sh
|
||||
scadabridge --url http://localhost:9001 <command>
|
||||
scadabridge --url http://localhost:9000 <command>
|
||||
```
|
||||
|
||||
For HA failover, use a load balancer URL. The management API is stateless (Basic Auth per request), so any central node can handle any request without sticky sessions.
|
||||
The management API is stateless (Basic Auth per request), so sticky sessions are unnecessary. Direct node URLs (`9001`/`9002`) are useful for diagnostics; use Traefik for active-node routing and failover.
|
||||
|
||||
## Global Options
|
||||
|
||||
@@ -107,6 +107,24 @@ scadabridge --url <url> --format json template list # unmodified JS
|
||||
| `--skip` | no | Offset paging: number of items to skip (default 0) |
|
||||
| `--take` | no | Offset paging: max items to return (clamped 1..1000; omit for unlimited) |
|
||||
|
||||
#### `template resolved-members`
|
||||
|
||||
Inspect effective template members, including inheritance. This does not apply composition or instance overrides.
|
||||
|
||||
```sh
|
||||
scadabridge template resolved-members --id <template-id>
|
||||
```
|
||||
|
||||
#### `template move`
|
||||
|
||||
Move a template into a folder, or to the root when `--folder-id` is omitted.
|
||||
|
||||
```sh
|
||||
scadabridge template move --id <template-id> [--folder-id <folder-id>]
|
||||
```
|
||||
|
||||
Requires Designer access; server-side folder and dependency checks apply.
|
||||
|
||||
#### `template get`
|
||||
|
||||
Get a single template by ID. Unlike `template list`, this returns the **full** template
|
||||
@@ -333,6 +351,16 @@ List the native alarm source bindings on a template.
|
||||
scadabridge --url <url> template native-alarm-source list --template-id <int>
|
||||
```
|
||||
|
||||
#### `template native-alarm-source update`
|
||||
|
||||
Replace the fields of an existing native alarm source binding.
|
||||
|
||||
```sh
|
||||
scadabridge template native-alarm-source update --id <source-id> --name <name> --connection <name> --source-ref <reference> [--filter <expression>] [--description <text>] [--locked]
|
||||
```
|
||||
|
||||
The ID, name, connection, and source reference are required. Omitted filter and description clear those values; omitted `--locked` means unlocked. Requires Designer access; the server enforces locking rules.
|
||||
|
||||
#### `template native-alarm-source remove`
|
||||
|
||||
Remove a native alarm source binding from a template (by its ID).
|
||||
@@ -566,6 +594,24 @@ Create Instance page can bind the module groups at creation time (design
|
||||
2026-08-21); the CLI equivalent is a follow-up `instance set-bindings` /
|
||||
`instance bind-module` against the new instance id.
|
||||
|
||||
#### `instance native-alarm-source list`
|
||||
|
||||
List the native alarm source overrides for an instance.
|
||||
|
||||
```sh
|
||||
scadabridge instance native-alarm-source list --instance-id <id>
|
||||
```
|
||||
|
||||
#### `instance attribute-override delete`
|
||||
|
||||
Delete one attribute override while preserving other overrides.
|
||||
|
||||
```sh
|
||||
scadabridge instance attribute-override delete --instance-id <id> --attribute <canonical-name>
|
||||
```
|
||||
|
||||
Use a composed name such as `Module.Speed` where applicable. Requires Deployer access and passes through server-side site-scope checks.
|
||||
|
||||
#### `instance native-alarm-source set`
|
||||
|
||||
Override an inherited native alarm source binding for a single instance (upsert). Blank
|
||||
@@ -1143,6 +1189,16 @@ scadabridge --url <url> data-connection update --id <int> --name <string> --prot
|
||||
| `--backup-config` | no | Backup protocol-specific configuration as a JSON string |
|
||||
| `--failover-retry-count` | no | Retries before failover to the backup configuration (default: `3`) |
|
||||
|
||||
#### `data-connection move`
|
||||
|
||||
Move a data connection to a destination site.
|
||||
|
||||
```sh
|
||||
scadabridge data-connection move --id <connection-id> --site-id <destination-site-id>
|
||||
```
|
||||
|
||||
Both IDs are required. Requires Designer access; the server validates the destination and any dependency restrictions.
|
||||
|
||||
#### `data-connection delete`
|
||||
|
||||
Delete a data connection.
|
||||
@@ -1326,6 +1382,48 @@ scadabridge --url <url> external-system delete --id <int>
|
||||
|
||||
---
|
||||
|
||||
#### `external-system method list`
|
||||
|
||||
List the methods belonging to an external system.
|
||||
|
||||
```sh
|
||||
scadabridge external-system method list --external-system-id <id>
|
||||
```
|
||||
|
||||
#### `external-system method get`
|
||||
|
||||
Read one method definition.
|
||||
|
||||
```sh
|
||||
scadabridge external-system method get --id <id>
|
||||
```
|
||||
|
||||
#### `external-system method create`
|
||||
|
||||
Create an external HTTP method. Requires Designer access.
|
||||
|
||||
```sh
|
||||
scadabridge external-system method create --external-system-id <id> --name <name> --http-method <verb> --path <path> [--params <json>] [--return <json>]
|
||||
```
|
||||
|
||||
#### `external-system method update`
|
||||
|
||||
Update an external HTTP method. Requires Designer access.
|
||||
|
||||
```sh
|
||||
scadabridge external-system method update --id <id> [--name <name>] [--http-method <verb>] [--path <path>] [--params <json>] [--return <json>]
|
||||
```
|
||||
|
||||
#### `external-system method delete`
|
||||
|
||||
Delete a method by ID. Requires Designer access.
|
||||
|
||||
```sh
|
||||
scadabridge external-system method delete --id <id>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `notification` — Manage notification lists
|
||||
|
||||
#### `notification get`
|
||||
@@ -1392,6 +1490,36 @@ scadabridge --url <url> notification update --id <int> --name <string> --type sm
|
||||
| `--emails` | conditional | Comma-separated recipient email addresses. **Required for `--type email`; rejected for `--type sms`.** |
|
||||
| `--phones` | conditional | Comma-separated recipient phone numbers in E.164. **Required for `--type sms`; rejected for `--type email`.** |
|
||||
|
||||
#### `notification rename`
|
||||
|
||||
Rename a list without replacing its recipients.
|
||||
|
||||
```sh
|
||||
scadabridge notification rename --id <list-id> --name <name>
|
||||
```
|
||||
|
||||
Requires Designer access. Unrelated recipient IDs, names, and contacts are preserved.
|
||||
|
||||
#### `notification recipient add`
|
||||
|
||||
Add an individual named recipient to an existing list.
|
||||
|
||||
```sh
|
||||
scadabridge notification recipient add --list-id <id> --name <name> [--email <email>] [--phone <E.164-number>]
|
||||
```
|
||||
|
||||
Provide at least one of `--email` or `--phone`. The server checks the contact against the owning list channel. Requires Designer access; other recipients remain unchanged.
|
||||
|
||||
#### `notification recipient delete`
|
||||
|
||||
Delete one recipient by recipient ID.
|
||||
|
||||
```sh
|
||||
scadabridge notification recipient delete --id <recipient-id>
|
||||
```
|
||||
|
||||
Requires Designer access. Only the specified recipient is removed.
|
||||
|
||||
#### `notification delete`
|
||||
|
||||
Delete a notification list.
|
||||
@@ -1412,6 +1540,16 @@ Show the current SMTP configuration.
|
||||
scadabridge --url <url> notification smtp list
|
||||
```
|
||||
|
||||
#### `notification smtp create`
|
||||
|
||||
Create a new SMTP configuration. Requires Administrator access.
|
||||
|
||||
```sh
|
||||
scadabridge notification smtp create --server <host> --port <int> --auth-mode <mode> --from-address <email> [--tls-mode <mode>] [--credentials <value>] [--oauth2-authority <url>] [--oauth2-scope <scope>] [--transport <Smtp|Ews>]
|
||||
```
|
||||
|
||||
Uses the same settings as `smtp update`, without `--id`. This sends the distinct create contract; update with ID zero is not a creation operation. The server validates transport/authentication compatibility.
|
||||
|
||||
#### `notification smtp update`
|
||||
|
||||
Update the SMTP configuration.
|
||||
@@ -1445,22 +1583,35 @@ Show the current SMS (Twilio) configuration. The Twilio **Auth Token is never re
|
||||
scadabridge --url <url> notification sms list
|
||||
```
|
||||
|
||||
#### `notification sms create`
|
||||
|
||||
Create a new Twilio configuration. Requires Administrator access.
|
||||
|
||||
```sh
|
||||
scadabridge notification sms create --account-sid <sid> --auth-token <token> [--from-number <E.164-number>] [--messaging-service-sid <sid>] [--api-base-url <url>] [--connection-timeout-seconds <n>] [--max-retries <n>] [--retry-delay-seconds <n>]
|
||||
```
|
||||
|
||||
Account SID and auth token are required. Supply at least one sender: `--from-number` or `--messaging-service-sid`. Timeout must be positive; retries/delay must be nonnegative. Omitted policy settings use creation defaults. Explicit zero retry settings retain the outbox fallback semantics; they do not disable retries.
|
||||
|
||||
#### `notification sms update`
|
||||
|
||||
Update the SMS (Twilio) configuration.
|
||||
|
||||
```sh
|
||||
scadabridge --url <url> notification sms update --id <int> --account-sid <string> --from-number <string> [--messaging-service-sid <string>] [--api-base-url <string>] [--auth-token <string>]
|
||||
scadabridge --url <url> notification sms update --id <int> --account-sid <string> [--from-number <string>] [--messaging-service-sid <string>] [--api-base-url <string>] [--auth-token <string>] [--connection-timeout-seconds <n>] [--max-retries <n>] [--retry-delay-seconds <n>]
|
||||
```
|
||||
|
||||
| Option | Required | Description |
|
||||
|--------|----------|-------------|
|
||||
| `--id` | yes | SMS config ID |
|
||||
| `--account-sid` | yes | Twilio Account SID |
|
||||
| `--from-number` | yes | Sender phone number (E.164) |
|
||||
| `--from-number` | conditional | Sender phone number (E.164); provide this and/or `--messaging-service-sid` |
|
||||
| `--messaging-service-sid` | no | Twilio Messaging Service SID. **Omitting it CLEARS the stored value** (the update overwrites it). |
|
||||
| `--api-base-url` | no | API base URL override (preserves existing if omitted) |
|
||||
| `--auth-token` | no | Twilio Auth Token. **Omitting it PRESERVES the stored token.** Never printed back. |
|
||||
| `--connection-timeout-seconds` | no | Positive timeout; omission preserves the existing value |
|
||||
| `--max-retries` | no | Nonnegative retry setting; omission preserves it; zero retains outbox fallback semantics |
|
||||
| `--retry-delay-seconds` | no | Nonnegative delay; omission preserves it; zero retains outbox fallback semantics |
|
||||
|
||||
---
|
||||
|
||||
@@ -1952,6 +2103,56 @@ single `Property`/`Value` cell (deferred-work register row 57).
|
||||
|
||||
---
|
||||
|
||||
### `shared-schema` — Manage the shared JSON schema library
|
||||
|
||||
Reads require authentication; create/update/delete require Designer access.
|
||||
|
||||
#### `shared-schema list`
|
||||
|
||||
List all shared schemas.
|
||||
|
||||
```sh
|
||||
scadabridge shared-schema list
|
||||
```
|
||||
|
||||
#### `shared-schema get`
|
||||
|
||||
Get one shared schema by ID.
|
||||
|
||||
```sh
|
||||
scadabridge shared-schema get --id <id>
|
||||
```
|
||||
|
||||
#### `shared-schema create`
|
||||
|
||||
Create a schema from a UTF-8 JSON file.
|
||||
|
||||
```sh
|
||||
scadabridge shared-schema create --name <name> --schema-file <path.json> [--scope <scope>]
|
||||
```
|
||||
|
||||
The CLI validates file readability and JSON syntax; the server validates schema structure and uniqueness.
|
||||
|
||||
#### `shared-schema update`
|
||||
|
||||
Replace a schema's name, scope, and document.
|
||||
|
||||
```sh
|
||||
scadabridge shared-schema update --id <id> --name <name> --schema-file <path.json> [--scope <scope>]
|
||||
```
|
||||
|
||||
The CLI validates file readability and JSON syntax; the server validates schema structure and uniqueness. Omit `--scope` to clear it on update.
|
||||
|
||||
#### `shared-schema delete`
|
||||
|
||||
Delete a shared schema by ID.
|
||||
|
||||
```sh
|
||||
scadabridge shared-schema delete --id <id>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `shared-script` — Manage shared scripts
|
||||
|
||||
#### `shared-script list`
|
||||
@@ -2270,9 +2471,9 @@ scadabridge --url <url> cached-call discard --site-id <string> --tracked-operati
|
||||
|
||||
---
|
||||
|
||||
### `secured-write` — Query two-person write requests
|
||||
### `secured-write` — Manage two-person write requests
|
||||
|
||||
`secured-write list` reads the MxGateway secured-write queue and terminal history. It requires any of Operator, Verifier or Administrator and applies the caller's site scope. This group also exposes `submit`, `approve`, and `reject` through the same server-side authorization and separation-of-duties checks as the UI; see the parity additions below.
|
||||
`secured-write list` reads the MxGateway secured-write queue and terminal history. It requires any of Operator, Verifier or Administrator and applies the caller's site scope. This group also exposes `submit`, `approve`, and `reject` through the same server-side authorization and separation-of-duties checks as the UI.
|
||||
|
||||
```sh
|
||||
scadabridge secured-write list --status Pending --site site-a --skip 0 --take 50
|
||||
@@ -2280,6 +2481,38 @@ scadabridge secured-write list --status Pending --site site-a --skip 0 --take 50
|
||||
|
||||
`--status` and `--site` are optional filters. `--skip` defaults to 0; `--take` defaults to 200 and is clamped server-side to 1–500. Global connection, authentication and output-format options apply.
|
||||
|
||||
#### `secured-write submit`
|
||||
|
||||
Submit a pending MxGateway write as an Operator. A distinct Verifier must approve or reject it.
|
||||
|
||||
```sh
|
||||
scadabridge secured-write submit --site <identifier> --connection <name> --tag-path <path> --value-json <json> --value-type <type> [--comment <text>]
|
||||
```
|
||||
|
||||
The first five options are required. JSON strings must include JSON quotes, for example `--value-json '"Auto"' --value-type String`. The server validates the type/value pairing and site scope and derives identity from authentication.
|
||||
|
||||
#### `secured-write approve`
|
||||
|
||||
Approve and execute a pending write as a Verifier. This can write to the real device.
|
||||
|
||||
```sh
|
||||
scadabridge secured-write approve --id <long> [--comment <text>]
|
||||
```
|
||||
|
||||
The 64-bit request ID is required. The server enforces a different principal from the submitter, expiry, site scope, and concurrent decision handling. Exit 0 requires `status: Executed`; a failed execution or invalid response exits 1, preserving response details. Authorization denial exits 2.
|
||||
|
||||
#### `secured-write reject`
|
||||
|
||||
Reject a pending write as a Verifier.
|
||||
|
||||
```sh
|
||||
scadabridge secured-write reject --id <long> [--comment <text>]
|
||||
```
|
||||
|
||||
The 64-bit request ID is required. The server enforces separation of duties and site scope. A rejection does not execute the device write.
|
||||
|
||||
---
|
||||
|
||||
### `flow-debug` — Trace an inbound API, script, or value-change flow end to end
|
||||
|
||||
The CLI face of the **Flow Debugger** (design `docs/plans/2026-09-05-flow-debugger-design.md`,
|
||||
@@ -2411,6 +2644,15 @@ run's outbound API / DB / notification rows, which are always audited.
|
||||
|
||||
---
|
||||
|
||||
## Deployment deadlines
|
||||
|
||||
`deploy instance`, `instance deploy`, `deploy artifacts`, `site deploy-artifacts`,
|
||||
and `deploy site` defer the overall deadline to the Management API. They keep the
|
||||
bounded socket-connect timeout but do not impose the ordinary 30-second client
|
||||
request deadline on a deployment that may still be applying. The API's configured
|
||||
long-running timeout remains authoritative. Ordinary commands retain a 30-second
|
||||
client deadline; explicit bundle/Flow Debugger timeouts retain their own policies.
|
||||
|
||||
## Architecture Notes
|
||||
|
||||
The CLI connects to the Central cluster over **HTTP** (`ManagementHttpClient`), posting to the `/management` endpoints at the configured `managementUrl` — normally the Traefik load balancer, which routes to the active central node. It carries HTTP **Basic** credentials from `--username`/`--password`. Central's endpoint handler asks the `ManagementActor` in-process via `ManagementActorHolder`.
|
||||
@@ -2419,109 +2661,21 @@ There is no Akka dependency in the CLI at all: it does not join the cluster, doe
|
||||
|
||||
An `HttpClient` is created per command invocation and disposed when the command completes.
|
||||
|
||||
Role enforcement is applied by the ManagementActor on the server side. The CLI authenticates against LDAP using `--username` / `--password`, resolves LDAP group memberships, then maps groups to ScadaBridge roles (Admin, Design, Deployment) via role mappings configured in the security settings. Operations require the appropriate role — for example, creating templates requires `Design`, deploying requires `Deployment`. In the test environment, use the `multi-role` user (password: `password`) which has all three roles.
|
||||
Role enforcement is applied by the ManagementActor on the server side. The CLI sends `--username` / `--password` as HTTP Basic credentials. The server performs LDAP authentication, resolves group memberships, and maps them to roles such as Administrator, Designer, and Deployer. Operations require the appropriate role — for example, creating templates requires `Designer`, deploying requires `Deployer`. In the test environment, use the `multi-role` user (password: `password`) which has all three roles.
|
||||
|
||||
## Issues & Missing Features
|
||||
|
||||
If you encounter bugs, unexpected behavior, or missing features in the CLI, log them in [`cli_issues.md`](../../cli_issues.md) in the project root. Include a brief description, the command involved, and any relevant error output.
|
||||
|
||||
|
||||
## Management parity additions (2026-09-10)
|
||||
|
||||
The production CLI exposes all 149 HTTP-eligible management contracts across 20
|
||||
command groups. `CliApplication.BuildRoot()` is used both by the executable and
|
||||
by the HTTP-dispatch parity test. Site-only `ReadTagValues` and the retired
|
||||
`ResolveRoles` flow are not accepted by `POST /management`; binding tests continue
|
||||
using the site's existing transport.
|
||||
All 149 HTTP-eligible management contracts are exposed across 20 command groups.
|
||||
The new operations are documented in their main command sections above, including
|
||||
[shared schemas](#shared-schema--manage-the-shared-json-schema-library),
|
||||
[notifications](#notification--manage-notification-lists), and
|
||||
[secured writes](#secured-write--manage-two-person-write-requests).
|
||||
[Deployment deadlines](#deployment-deadlines) apply to all deployment aliases.
|
||||
|
||||
### Shared schema library
|
||||
|
||||
```sh
|
||||
scadabridge shared-schema list
|
||||
scadabridge shared-schema get --id 7
|
||||
scadabridge shared-schema create --name PumpPayload --schema-file ./pump.schema.json --scope Pump
|
||||
scadabridge shared-schema update --id 7 --name PumpPayload --schema-file ./pump.schema.json
|
||||
scadabridge shared-schema delete --id 7
|
||||
```
|
||||
|
||||
Create/update read UTF-8 JSON from `--schema-file`; the server validates schema
|
||||
structure and uniqueness. Update replaces the name, schema, and scope; omitting
|
||||
`--scope` clears it. Mutations require Designer access.
|
||||
|
||||
### Individual notification edits and provider creation
|
||||
|
||||
```sh
|
||||
scadabridge notification rename --id 4 --name "Shift engineers"
|
||||
scadabridge notification recipient add --list-id 4 --name "On-call engineer" --email engineer@example.com
|
||||
scadabridge notification recipient delete --id 18
|
||||
scadabridge notification smtp create --server smtp.example.com --port 587 --auth-mode None --from-address alerts@example.com
|
||||
scadabridge notification sms create --account-sid AC0123456789abcdef0123456789abcdef --from-number +15551234567 --auth-token "<token>"
|
||||
```
|
||||
|
||||
Rename and individual recipient edits preserve unrelated recipient IDs and names.
|
||||
Recipient add accepts `--email` and/or `--phone`; the server checks them against
|
||||
its owning list's channel. Existing `notification update` retains its whole-list
|
||||
recipient replacement semantics.
|
||||
|
||||
SMTP/SMS create accept their update options except `--id` and send distinct create
|
||||
contracts. SMS create requires an auth token and a sender (`--from-number` and/or
|
||||
`--messaging-service-sid`). Provider creation/update requires Administrator access.
|
||||
|
||||
SMS create and update also accept:
|
||||
|
||||
| Option | Meaning |
|
||||
|---|---|
|
||||
| `--connection-timeout-seconds` | Positive connection timeout |
|
||||
| `--max-retries` | Nonnegative retry setting |
|
||||
| `--retry-delay-seconds` | Nonnegative retry delay |
|
||||
|
||||
Omission preserves existing update values or uses creation defaults. Explicit
|
||||
zero retry settings retain the existing outbox fallback semantics; they do not
|
||||
promise that delivery will never retry. Existing secret-preservation and
|
||||
messaging-service-ID clearing behavior on update is unchanged.
|
||||
|
||||
### Template, instance, and connection edits
|
||||
|
||||
```sh
|
||||
scadabridge template resolved-members --id 3
|
||||
scadabridge template move --id 3 --folder-id 8
|
||||
scadabridge template native-alarm-source update --id 5 --name Pressure --connection Plc --source-ref Pressure --locked
|
||||
scadabridge instance attribute-override delete --instance-id 7 --attribute Module.Speed
|
||||
scadabridge instance native-alarm-source list --instance-id 7
|
||||
scadabridge data-connection move --id 9 --site-id 2
|
||||
```
|
||||
|
||||
`resolved-members` inspects effective inherited template members, without applying
|
||||
composition or instance overrides. Omit `--folder-id` to move a template to the
|
||||
root. Native-alarm-source update replaces all contract fields: optional `--filter`
|
||||
and `--description` clear when omitted, and omitted `--locked` means false.
|
||||
Individual attribute-override deletion preserves other overrides. Server-side
|
||||
role, site-scope, locking, and dependency checks remain authoritative.
|
||||
|
||||
### Secured-write lifecycle
|
||||
|
||||
```sh
|
||||
scadabridge secured-write submit --site site-a --connection Plc --tag-path Pump.Setpoint --value-json 42 --value-type Int32 --comment "Approved operating procedure"
|
||||
scadabridge secured-write approve --id 123 --comment "Verified setpoint"
|
||||
scadabridge secured-write reject --id 124 --comment "Incorrect target"
|
||||
```
|
||||
|
||||
Submit requires Operator access; approve/reject require Verifier access. The
|
||||
server derives identity from authentication and enforces a different principal
|
||||
for the verification decision. Approval can execute a real device write.
|
||||
`--value-json` must be valid JSON; the server validates the value/type pairing.
|
||||
IDs for approve/reject are 64-bit integers; `--comment` is optional.
|
||||
|
||||
Approval exits zero only for an `Executed` response. A server-reported execution
|
||||
failure exits one while retaining the response details; malformed or unexpected
|
||||
approval responses also fail. Authorization denial exits two. JSON/table output
|
||||
continues to use the standard formatter.
|
||||
|
||||
### Deployment deadline policy
|
||||
|
||||
`deploy instance`, `instance deploy`, `deploy artifacts`, `site deploy-artifacts`,
|
||||
and `deploy site` defer the overall deadline to the Management API. They keep the
|
||||
bounded socket-connect timeout but do not impose the ordinary 30-second client
|
||||
request deadline on a deployment that may still be applying. The API's configured
|
||||
long-running timeout remains authoritative. Ordinary commands retain a 30-second
|
||||
client deadline; explicit bundle/Flow Debugger timeouts retain their own policies.
|
||||
`CliApplication.BuildRoot()` constructs the executable command tree and the tree
|
||||
used by the HTTP parity test. Site-only `ReadTagValues` and retired `ResolveRoles`
|
||||
are excluded from `POST /management`; site binding tests retain their transport.
|
||||
|
||||
Reference in New Issue
Block a user