# 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 ```sh 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: 1. `--contact-points` flag on the command line 2. `SCADALINK_CONTACT_POINTS` environment variable 3. `contactPoints` array in `~/.scadalink/config.json` ```sh scadalink --contact-points akka.tcp://scadalink@central-host:8081 ``` For a two-node HA cluster, supply both nodes comma-separated: ```sh scadalink --contact-points akka.tcp://scadalink@node1:8081,akka.tcp://scadalink@node2:8082 ``` ## Global Options These options are accepted by the root command and inherited by all subcommands. | Option | Description | |--------|-------------| | `--contact-points ` | Comma-separated Akka cluster contact point URIs | | `--username ` | LDAP username (reserved for future auth integration) | | `--password ` | LDAP password (reserved for future auth integration) | | `--format ` | Output format (default: `json`) | ## Configuration File `~/.scadalink/config.json` is loaded at startup. All fields are optional. ```json { "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: ```json { "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. ```sh scadalink --contact-points template list ``` #### `template get` Get a single template by ID. ```sh scadalink --contact-points template get --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Template ID | #### `template create` Create a new template, optionally inheriting from a parent. ```sh scadalink --contact-points template create --name [--description ] [--parent-id ] ``` | 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. ```sh scadalink --contact-points template delete --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Template ID | --- ### `instance` — Manage instances #### `instance list` List instances, with optional filters. ```sh scadalink --contact-points instance list [--site-id ] [--template-id ] [--search ] ``` | 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. ```sh scadalink --contact-points instance create --name --template-id --site-id [--area-id ] ``` | 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. ```sh scadalink --contact-points instance deploy --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Instance ID | #### `instance enable` Enable a previously disabled instance. ```sh scadalink --contact-points instance enable --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Instance ID | #### `instance disable` Disable a running instance without deleting it. ```sh scadalink --contact-points instance disable --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Instance ID | #### `instance delete` Delete an instance. The instance must be disabled first. ```sh scadalink --contact-points instance delete --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Instance ID | --- ### `site` — Manage sites #### `site list` List all registered sites. ```sh scadalink --contact-points site list ``` #### `site create` Register a new site. ```sh scadalink --contact-points site create --name --identifier [--description ] ``` | 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. ```sh scadalink --contact-points site delete --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Site ID | #### `site deploy-artifacts` Push compiled artifacts to one or all sites. ```sh scadalink --contact-points site deploy-artifacts [--site-id ] ``` | 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`). ```sh scadalink --contact-points deploy instance --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Instance ID | #### `deploy artifacts` Deploy compiled artifacts to one or all sites (same as `site deploy-artifacts`). ```sh scadalink --contact-points deploy artifacts [--site-id ] ``` | Option | Required | Description | |--------|----------|-------------| | `--site-id` | no | Target site ID; omit for all sites | #### `deploy status` Query deployment records, with optional filters and pagination. ```sh scadalink --contact-points deploy status [--instance-id ] [--status ] [--page ] [--page-size ] ``` | 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. ```sh scadalink --contact-points data-connection list ``` #### `data-connection create` Create a new data connection definition. ```sh scadalink --contact-points data-connection create --name --protocol [--configuration ] ``` | 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. ```sh scadalink --contact-points data-connection delete --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Data connection ID | #### `data-connection assign` Assign a data connection to a site. ```sh scadalink --contact-points data-connection assign --connection-id --site-id ``` | 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. ```sh scadalink --contact-points external-system list ``` #### `external-system create` Register an external HTTP system that scripts can call. ```sh scadalink --contact-points external-system create --name --endpoint-url --auth-type [--auth-config ] ``` | 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. ```sh scadalink --contact-points external-system delete --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | External system ID | --- ### `notification` — Manage notification lists #### `notification list` List all notification lists. ```sh scadalink --contact-points notification list ``` #### `notification create` Create a notification list with one or more recipients. ```sh scadalink --contact-points notification create --name --emails ``` | Option | Required | Description | |--------|----------|-------------| | `--name` | yes | Notification list name | | `--emails` | yes | Comma-separated list of recipient email addresses | #### `notification delete` Delete a notification list. ```sh scadalink --contact-points notification delete --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | Notification list ID | --- ### `security` — Security settings #### `security api-key list` List all inbound API keys. ```sh scadalink --contact-points 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. ```sh scadalink --contact-points security api-key create --name ``` | Option | Required | Description | |--------|----------|-------------| | `--name` | yes | Descriptive label for the key | #### `security api-key delete` Revoke and delete an API key. ```sh scadalink --contact-points security api-key delete --id ``` | Option | Required | Description | |--------|----------|-------------| | `--id` | yes | API key ID | #### `security role-mapping list` List all LDAP group → role mappings. ```sh scadalink --contact-points security role-mapping list ``` #### `security role-mapping create` Map an LDAP group to a ScadaLink role. ```sh scadalink --contact-points security role-mapping create --ldap-group --role ``` | 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. ```sh scadalink --contact-points security role-mapping delete --id ``` | 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. ```sh scadalink --contact-points health summary ``` #### `health site` Return the health state for a single site. ```sh scadalink --contact-points health site --identifier ``` | 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. ```sh scadalink --contact-points 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`.