Control CLI cookbook
This document provides step-by-step instructions for bootstrapping and enrolling RADKit Service, then adding and updating users and devices, over the network using the RADKit Control CLI.
Warning
This procedure is for illustration purposes only. There are many possible ways to deploy RADKit Service and to use RADKit Control; you may need to adjust the steps below depending on your particular situation. Please make sure that you have read the Service and Control documentation and performed thorough testing before you attempt such a deployment in production.
Prerequisites
The instructions assume that you are using Linux, macOS or WSL and are already familiar with RADKit Client and Service.
RADKit Control is part of the RADKit Service package. In other words, you must install RADKit Service on both the host where you want to deploy RADKit Service, and the host from which you want to remotely configure RADKit Service. Those do not have to be the same platform, but they do have to use the same version of RADKit.
Bootstrap the Service
Open a command-line interface on the host where RADKit Service will be deployed.
Bootstrap RADKit Service and set a
superadmin
password, then start the Service:$ radkit-service bootstrap ... Set up the superadmin user. You'll be asked to provide a superadmin password. Keep this password securely stored, as it will be impossible to recover it! Superadmin password (for new setup): ********* Confirm: ********* ... Bootstrapping is complete. The next step is to enroll with the RADKit Certificate Authority. You can now start the Service with 'radkit-service run' and log on to the WebUI as 'superadmin'. Alternatively, you can enroll through the CLI (see documentation for details). $ radkit-service run ... Superadmin password: ********* [correct] ... 15:25:29.216Z INFO | internal | UI and API listener started [addresses=['[::]'] secure_port=8081] 15:25:29.325Z INFO | internal | Running on https://[::]:8081 (CTRL + C to quit)
Note
It is also possible to simply start the un-bootstrapped Service using
radkit-service run
and then bootstrap remotely usingradkit-control admin create --initial superadmin
, however that method currently does not allow to verify the Service TLS certificate; it is therefore recommended to bootstrap the Service locally and export the webserver certificate or its fingerprint to ensure a properly secured deployment process.Write down the Service API TLS certificate fingerprint displayed in the logs on startup:
13:59:05.364Z INFO | internal | Webserver certificate fingerprint [fingerprint='b555...d358']`
Warning
Do not confuse the
Webserver certificate fingerprint
with the unrelatedE2EE certificate fingerprint
.
Set up Control
Open a command-line interface on the host where RADKit Control will be used to remotely manage RADKit Service.
Create a TOML configuration file for Control (see Settings management and Control settings for more information).
First create the
control
directory under yourRADKIT_DIRECTORY
:$ mkdir -p ~/.radkit/control/
Then create
settings.toml
within that directory and adjust the values to your situation:~/.radkit/control/settings.toml[control] service_url = "https://my-radkit-service-host:8081/api/v1" admin_name = "superadmin" service_fingerprint = "b555...d358"
Verify connectivity by issuing the
system status
subcommand:% radkit-control system status superadmin's password: { "success": true, "result": { "version": "...", "username": "superadmin", "bootstrapped": true, "cloud_rpc_enabled": true, "direct_rpc_enabled": true, "cloud": { "domain": "PROD", "base_url": "https://prod.radkit-cloud.cisco.com", "enrolled": false, "service_id": null, "connected": false, "connected_message": "DISCONNECTED" }, "e2ee_sha256_fingerprint": "...", "webserver_sha256_fingerprint": "..." } }
Note "enrolled": false
in the results. You can now proceed with enrolling the Service.
Enroll the Service
Log on to RADKit Cloud from RADKit Client and generate an OTP for your Service:
>>> client = sso_login("radkit-user@example.com") >>> client.grant_service_otp() ... ----------- ----------------------- email radkit-user@example.com serial aaaa-bbbb-cccc otp 1234-2345-3456 domain_name PROD ----------- ----------------------- ...
The domain-qualified OTP is
PROD:1234-2345-3456
.Enroll the Service remotely using
system enroll
(this can take a few seconds):$ radkit-control system enroll PROD:1234-2345-3456 superadmin's password: { "success": true, "result": "Service successfully enrolled and started" }
Verify the output of
system status
:% radkit-control system status superadmin's password: { "success": true, "result": { "version": "...", "username": "superadmin", "bootstrapped": true, "cloud_rpc_enabled": true, "direct_rpc_enabled": true, "cloud": { "domain": "PROD", "base_url": "https://prod.radkit-cloud.cisco.com", "enrolled": true, "service_id": "aaaa-bbbb-cccc", "connected": true, "connected_message": "CONNECTED" }, "e2ee_sha256_fingerprint": "...", "webserver_sha256_fingerprint": "..." } }
Note the presence of "enrolled": true
, "service_id": "aaaa-bbbb-cccc"
and
"connected_message": "CONNECTED"
in the results.
Create an admin account
Create an admin account and set a password for it using
admin create
:$ radkit-control admin create --full-name "My Admin" myadmin Provide a password for myadmin: superadmin's password: { "success": true, "result": { "username": "myadmin", "email": "", "fullname": "My Admin", "description": "" } }
Verify the list of admins using
admin list
:$ radkit-control admin list superadmin's password: { "success": true, "result": [ { "username": "superadmin", "email": "", "fullname": "", "description": "" }, { "username": "myadmin", "email": "", "fullname": "My Admin", "description": "" } ] }
Set up Control to start using this new admin account by changing the
admin_name
setting:~/.radkit/control/settings.toml[control] ... admin_name = "myadmin"
Control is now going to prompt for the password of
myadmin
instead ofsuperadmin
.
Note
Only superadmin
is allowed to manage other admin accounts. It is preferable to switch
to another admin account if you are only going to manage remote users and devices, and
restrict the use of superadmin
to specific tasks, such as managing admins or starting
the Service.
Create a remote user
Create and activate a remote user for yourself using user create
:
% radkit-control user create --full-name "My User" --active forever radkit-user@example.com superadmin's password: { "success": true, "result": { "username": "radkit-user@example.com", "fullname": "My User", "description": "", "timeSliceMinutes": null, "expirationTimestamp": null, "labels": [] } }
Create, update and interact with a device
Create and activate a single device using
device create
:% radkit-control device create --description "My first device" --active true \ --terminal-username example my-csr2 example-csr2.example.com IOS_XE myadmin's password: Device SSH password: { "success": true, "result": { "uuid": "006c91de-27f2-44be-ac15-cdb17cd84f20", "name": "csr2", "host": "example-csr2.cisco.com", "deviceType": "IOS_XE", "description": "My first device", "labels": [], "jumphostUuid": null, "sourceKey": null, "sourceDevUuid": null, "metaData": [], "enabled": true, "terminal": { "port": 22, "connectionMethod": "SSH", "username": "example", "enableSet": false, "useInsecureAlgorithms": false, "useTunnelingIfJumphost": true, "provisioningVariant": "DEFAULT" }, "netconf": null, "swagger": null, "http": null, "forwardedTcpPorts": "" } }
Since you configured the device for Terminal/SSH access and did not pass
--terminal-password ...
on the command-line, you were prompted for the SSH password for the device. This is safer than typing the password in the clear and leaving it in the shell history and/or terminal scrollback buffer.The device was allocated a UUID by the Service, in our example
006c91de-27f2-44be-ac15-cdb17cd84f20
. This will be the unique identifier by which you will refer to this device in RADKit Control.Try renaming the device using
device update
, specifying the device UUID:$ radkit-control device update --name csr2 006c91de-27f2-44be-ac15-cdb17cd84f20 myadmin's password: { "success": true, ... }
Start a RADKit Client, authenticate using SSO, and list the Service inventory:
>>> c = sso_login("radkit-user@example.com") >>> s = c.service("aaaa-bbbb-cccc") 19:07:08.794Z INFO | internal | Connecting to forwarder [uri='wss://prod.radkit-cloud.cisco.com/forwarder-3/websocket/'] 19:07:08.887Z INFO | internal | Connection to forwarder successful [uri='wss://prod.radkit-cloud.cisco.com/forwarder-3/websocket/'] >>> s.inventory <radkit_client.sync.device.DeviceDict object at 0x10b1cddb0> name host device_type Terminal Netconf Swagger HTTP description failed ------ ---------------------- ------------- ---------- --------- --------- ------ --------------- -------- csr2 example-csr2.cisco.com IOS_XE True False False False My first device False Untouched inventory from service aaaa-bbbb-cccc. >>>
Try interacting over SSH with the device you created:
>>> device = service.inventory['csr2'] >>> device.interactive() 21:09:17.692Z INFO | internal | Starting interactive session (will be closed when detached) 21:09:17.998Z INFO | internal | Session log initialized [filepath='.....log'] Attaching to example-csr2.cisco.com ... Type: ~. to terminate. ~? for other shortcuts. When using nested SSH sessions, add an extra ~ per level of nesting. Warning: all sessions are logged. Never type passwords or other secrets, except at an echo-less password prompt.
Create multiple devices in bulk from a CSV source with terminal defined
Add the option
--help
toradkit-control device bulk-create
% radkit-control device bulk-create --help Usage: radkit-control device bulk-create [OPTIONS] Create multiple devices using JSON. Provide json in a file with --input, or directly with --json Options: --json-input FILENAME JSON file to pass to the API --json-data JSON JSON text to pass to the API --csv-input FILENAME CSV file to pass to the API --csv-data TEXT CSV text to pass to the API --json-template Show JSON template --csv-template Show CSV template. Use `terminal`, `http`, `swagger`, `netconf` or `labels` to generate substructures --output FILENAME Save JSON response to a file instead of displaying it --compact-json Output JSON response on one line --help Show this message and exit.
Based on the output, choose the option
--csv-template
to display it. You can complement this withterminal
,http
,snmp
swagger
,netconf
orlabels
substructures. In this example we will test terminal, as shown below:% radkit-control device bulk-create --csv-template terminal name(mandatory),host(mandatory),deviceType(mandatory),description,jumphostUuid,sourceKey,sourceDevUuid,metaData,enabled,snmp,forwardedTcpPorts,terminal.port,terminal.connectionMethod,terminal.username,terminal.enableSet,terminal.useInsecureAlgorithms,terminal.useTunnelingIfJumphost,terminal.password,terminal.enable,terminal.privateKeyPassword,terminal.privateKey Example: name,host,deviceType,description test-router1,1.1.1.1,IOS_XE,test router1 test-router2,1.1.1.2,IOS_XE,test router2
Start building your csv file, first by understanding each field and what values are accepted:
The mandatory fields are
name
,host
anddeviceType
. The rest of the fields are optional they have default values specified. These options will take their default values if not provided by the user.Example format for file.csv contents:
name(mandatory),host(mandatory),deviceType(mandatory),description,jumphostUuid,sourceKey,sourceDevUuid,metaData,enabled,forwardedTcpPorts,terminal.port,terminal.connectionMethod,terminal.username,terminal.enableSet,terminal.useInsecureAlgorithms,terminal.useTunnelingIfJumphost,terminal.password,terminal.enable,terminal.privateKeyPassword,terminal.privateKey asr9001,1.2.3.4,IOS_XR,test router1,,,,,True,,22,SSH,my-username,,,,my-strong-password,True,, test-router2,1.1.1.2,IOS_XE,test router2,,,,,,,,,,,,,,,,
See Devices for more information on the fields and expected values.
% radkit-control device bulk-create --csv-input file.csv superadmin's password: { "results": [....], "success": true, "count": 5, "success_count": 5 }