Two Akka.NET deserialization bugs prevented CLI commands from reaching ManagementActor: IReadOnlyList<string> in AuthenticatedUser serialized as a compiler-generated internal type unknown to the server, and ManagementSuccess.Data carried server-side assembly types the CLI couldn't resolve on receipt. Fixed by using string[] for roles and pre-serializing response data to JSON in ManagementActor before sending. Adds full CLI reference documentation covering all 10 command groups.
14 KiB
ScadaLink CLI
Command-line tool for managing the ScadaLink SCADA system. Connects to a Central node via Akka.NET ClusterClient and routes commands through the ManagementActor.
Installation
dotnet build src/ScadaLink.CLI
The output binary is scadalink (or scadalink.exe on Windows).
Connection
Every command requires a connection to a running Central node. Contact points can be supplied three ways, evaluated in this priority order:
--contact-pointsflag on the command lineSCADALINK_CONTACT_POINTSenvironment variablecontactPointsarray in~/.scadalink/config.json
scadalink --contact-points akka.tcp://scadalink@central-host:8081 <command>
For a two-node HA cluster, supply both nodes comma-separated:
scadalink --contact-points akka.tcp://scadalink@node1:8081,akka.tcp://scadalink@node2:8082 <command>
Global Options
These options are accepted by the root command and inherited by all subcommands.
| Option | Description |
|---|---|
--contact-points <value> |
Comma-separated Akka cluster contact point URIs |
--username <value> |
LDAP username (reserved for future auth integration) |
--password <value> |
LDAP password (reserved for future auth integration) |
--format <json|table> |
Output format (default: json) |
Configuration File
~/.scadalink/config.json is loaded at startup. All fields are optional.
{
"contactPoints": ["akka.tcp://scadalink@central-host:8081"],
"ldap": {
"server": "ldap.company.com",
"port": 636,
"useTls": true
},
"defaultFormat": "json"
}
Environment Variables
| Variable | Description |
|---|---|
SCADALINK_CONTACT_POINTS |
Comma-separated contact point URIs (overrides config file) |
SCADALINK_LDAP_SERVER |
LDAP server hostname (overrides config file) |
SCADALINK_FORMAT |
Default output format (overrides config file) |
Output
All commands write JSON to stdout on success. Errors are written as JSON to stderr:
{ "error": "Human-readable message", "code": "ERROR_CODE" }
Exit codes:
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Command error |
2 |
Authorization failure |
Command Reference
template — Manage templates
template list
List all templates with their full attribute, alarm, script, and composition definitions.
scadalink --contact-points <uri> template list
template get
Get a single template by ID.
scadalink --contact-points <uri> template get --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Template ID |
template create
Create a new template, optionally inheriting from a parent.
scadalink --contact-points <uri> template create --name <string> [--description <string>] [--parent-id <int>]
| Option | Required | Description |
|---|---|---|
--name |
yes | Template name |
--description |
no | Template description |
--parent-id |
no | Parent template ID for inheritance |
template delete
Delete a template by ID.
scadalink --contact-points <uri> template delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Template ID |
instance — Manage instances
instance list
List instances, with optional filters.
scadalink --contact-points <uri> instance list [--site-id <int>] [--template-id <int>] [--search <string>]
| Option | Required | Description |
|---|---|---|
--site-id |
no | Filter by site ID |
--template-id |
no | Filter by template ID |
--search |
no | Search term matched against instance name |
instance create
Create a new instance of a template at a site.
scadalink --contact-points <uri> instance create --name <string> --template-id <int> --site-id <int> [--area-id <int>]
| Option | Required | Description |
|---|---|---|
--name |
yes | Unique instance name |
--template-id |
yes | Template to instantiate |
--site-id |
yes | Site where the instance will run |
--area-id |
no | Area within the site |
instance deploy
Deploy an instance to its site. Acquires the per-instance operation lock.
scadalink --contact-points <uri> instance deploy --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Instance ID |
instance enable
Enable a previously disabled instance.
scadalink --contact-points <uri> instance enable --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Instance ID |
instance disable
Disable a running instance without deleting it.
scadalink --contact-points <uri> instance disable --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Instance ID |
instance delete
Delete an instance. The instance must be disabled first.
scadalink --contact-points <uri> instance delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Instance ID |
site — Manage sites
site list
List all registered sites.
scadalink --contact-points <uri> site list
site create
Register a new site.
scadalink --contact-points <uri> site create --name <string> --identifier <string> [--description <string>]
| Option | Required | Description |
|---|---|---|
--name |
yes | Human-readable site name |
--identifier |
yes | Unique machine identifier used for cluster routing (e.g. site-a) |
--description |
no | Site description |
site delete
Delete a site. Fails if any instances are assigned to it.
scadalink --contact-points <uri> site delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Site ID |
site deploy-artifacts
Push compiled artifacts to one or all sites.
scadalink --contact-points <uri> site deploy-artifacts [--site-id <int>]
| Option | Required | Description |
|---|---|---|
--site-id |
no | Target site ID; omit to deploy to all sites |
deploy — Deployment operations
deploy instance
Deploy a single instance (same as instance deploy).
scadalink --contact-points <uri> deploy instance --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Instance ID |
deploy artifacts
Deploy compiled artifacts to one or all sites (same as site deploy-artifacts).
scadalink --contact-points <uri> deploy artifacts [--site-id <int>]
| Option | Required | Description |
|---|---|---|
--site-id |
no | Target site ID; omit for all sites |
deploy status
Query deployment records, with optional filters and pagination.
scadalink --contact-points <uri> deploy status [--instance-id <int>] [--status <string>] [--page <int>] [--page-size <int>]
| Option | Required | Default | Description |
|---|---|---|---|
--instance-id |
no | — | Filter by instance ID |
--status |
no | — | Filter by deployment status string |
--page |
no | 1 |
Page number |
--page-size |
no | 50 |
Results per page |
data-connection — Manage data connections
data-connection list
List all configured data connections.
scadalink --contact-points <uri> data-connection list
data-connection create
Create a new data connection definition.
scadalink --contact-points <uri> data-connection create --name <string> --protocol <string> [--configuration <json>]
| Option | Required | Description |
|---|---|---|
--name |
yes | Connection name |
--protocol |
yes | Protocol identifier (e.g. OpcUa) |
--configuration |
no | Protocol-specific configuration as a JSON string |
data-connection delete
Delete a data connection.
scadalink --contact-points <uri> data-connection delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Data connection ID |
data-connection assign
Assign a data connection to a site.
scadalink --contact-points <uri> data-connection assign --connection-id <int> --site-id <int>
| Option | Required | Description |
|---|---|---|
--connection-id |
yes | Data connection ID |
--site-id |
yes | Site ID |
external-system — Manage external HTTP systems
external-system list
List all external system definitions.
scadalink --contact-points <uri> external-system list
external-system create
Register an external HTTP system that scripts can call.
scadalink --contact-points <uri> external-system create --name <string> --endpoint-url <url> --auth-type <string> [--auth-config <json>]
| Option | Required | Description |
|---|---|---|
--name |
yes | Display name |
--endpoint-url |
yes | Base URL of the external system |
--auth-type |
yes | Authentication type: ApiKey or BasicAuth |
--auth-config |
no | Auth credentials as a JSON string |
external-system delete
Delete an external system definition.
scadalink --contact-points <uri> external-system delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | External system ID |
notification — Manage notification lists
notification list
List all notification lists.
scadalink --contact-points <uri> notification list
notification create
Create a notification list with one or more recipients.
scadalink --contact-points <uri> notification create --name <string> --emails <email1,email2,...>
| Option | Required | Description |
|---|---|---|
--name |
yes | Notification list name |
--emails |
yes | Comma-separated list of recipient email addresses |
notification delete
Delete a notification list.
scadalink --contact-points <uri> notification delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Notification list ID |
security — Security settings
security api-key list
List all inbound API keys.
scadalink --contact-points <uri> security api-key list
security api-key create
Create a new inbound API key. The generated key value is returned in the response and not stored in plaintext — save it immediately.
scadalink --contact-points <uri> security api-key create --name <string>
| Option | Required | Description |
|---|---|---|
--name |
yes | Descriptive label for the key |
security api-key delete
Revoke and delete an API key.
scadalink --contact-points <uri> security api-key delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | API key ID |
security role-mapping list
List all LDAP group → role mappings.
scadalink --contact-points <uri> security role-mapping list
security role-mapping create
Map an LDAP group to a ScadaLink role.
scadalink --contact-points <uri> security role-mapping create --ldap-group <string> --role <string>
| Option | Required | Description |
|---|---|---|
--ldap-group |
yes | LDAP group distinguished name or CN |
--role |
yes | ScadaLink role: Admin, Design, or Deployment |
security role-mapping delete
Remove an LDAP role mapping.
scadalink --contact-points <uri> security role-mapping delete --id <int>
| Option | Required | Description |
|---|---|---|
--id |
yes | Mapping ID |
health — Health monitoring
health summary
Return the current health state for all known sites as a JSON object keyed by site identifier.
scadalink --contact-points <uri> health summary
health site
Return the health state for a single site.
scadalink --contact-points <uri> health site --identifier <string>
| Option | Required | Description |
|---|---|---|
--identifier |
yes | Site identifier (e.g. site-a) |
audit-log — Audit log queries
audit-log query
Query the central audit log with optional filters and pagination.
scadalink --contact-points <uri> audit-log query [options]
| Option | Required | Default | Description |
|---|---|---|---|
--user |
no | — | Filter by username |
--entity-type |
no | — | Filter by entity type (e.g. Template, Instance) |
--action |
no | — | Filter by action (e.g. Create, Delete) |
--from |
no | — | Start timestamp in ISO 8601 format |
--to |
no | — | End timestamp in ISO 8601 format |
--page |
no | 1 |
Page number |
--page-size |
no | 50 |
Results per page |
Architecture Notes
The CLI connects to the Central cluster using Akka.NET's ClusterClient. It does not join the cluster — it contacts the ClusterClientReceptionist on one of the configured Central nodes and sends commands to the ManagementActor at path /user/management.
The connection is established per-command invocation and torn down cleanly via CoordinatedShutdown when the command completes.
Role enforcement is applied by the ManagementActor on the server side. The current CLI placeholder user carries Admin, Design, and Deployment roles; production use will integrate LDAP authentication via --username / --password.