nethsm_cli/cli/
system.rs

1use std::path::PathBuf;
2
3use chrono::{DateTime, Utc};
4use clap::{Parser, Subcommand};
5use expression_format::ex_format;
6use nethsm::{
7    SystemState::{Locked, Operational, Unprovisioned},
8    UserRole::{Administrator, Backup},
9};
10
11use super::BIN_NAME;
12use crate::passphrase_file::PassphraseFile;
13
14/// The "nethsm system" command.
15#[derive(Debug, Subcommand)]
16#[command(about = "Do system actions for a device")]
17pub enum SystemCommand {
18    /// The "nethsm system backup" command.
19    Backup(SystemBackupCommand),
20    /// The "nethsm system factory-reset" command.
21    FactoryReset(SystemFactoryResetCommand),
22    /// The "nethsm system info" command.
23    Info(SystemInfoCommand),
24    /// The "nethsm system reboot" command.
25    Reboot(SystemRebootCommand),
26    /// The "nethsm system restore" command.
27    Restore(SystemRestoreCommand),
28    /// The "nethsm system shutdown" command.
29    Shutdown(SystemShutdownCommand),
30    /// The "nethsm system upload-update" command.
31    UploadUpdate(SystemUploadUpdateCommand),
32    /// The "nethsm system cancel-update" command.
33    CancelUpdate(SystemCancelUpdateCommand),
34    /// The "nethsm system commit-update" command.
35    CommitUpdate(SystemCommitUpdateCommand),
36    /// The "nethsm system validate-backup" command.
37    ValidateBackup(SystemValidateBackupCommand),
38}
39
40#[derive(Debug, Parser)]
41#[command(
42    about = "Backup the key store of a device",
43    long_about = ex_format!("Backup the key store of a device
44
45Writes an encrypted backup to a file in the current working directory, named after the device label in the configuration file and the current time.
46Optionally, a specific output file can be provided.
47
48Note: Requires setting the backup passphrase using \"{BIN_NAME} config set backup-passphrase\" first!
49
50Requires authentication of a system-wide user in the \"{Backup}\" role.")
51)]
52pub struct SystemBackupCommand {
53    #[arg(
54        env = "NETHSM_FORCE",
55        help = "Write to output file even if it exists already",
56        long,
57        short
58    )]
59    pub force: bool,
60
61    #[arg(
62        env = "NETHSM_BACKUP_OUTPUT_FILE",
63        help = "The optional path to a specific output file",
64        long,
65        short
66    )]
67    pub output: Option<PathBuf>,
68}
69
70#[derive(Debug, Parser)]
71#[command(
72    about = "Reset the device to factory settings",
73    long_about = ex_format!("Reset the device to factory settings
74
75Triggers a factory reset for the device.
76
77**WARNING**: This action deletes all user and system data! Make sure to create a backup using \"{BIN_NAME} system backup\" first!
78
79Requires authentication of a system-wide user in the \"{Administrator}\" role.")
80)]
81pub struct SystemFactoryResetCommand {}
82
83#[derive(Debug, Parser)]
84#[command(
85    about = "Retrieve system information of a device",
86    long_about = ex_format!("Retrieve system information of a device
87
88Provides information on software version, software build, firmware version, hardware version, device ID and information related to TPM and PCR.
89
90Requires authentication of a system-wide user in the \"{Administrator}\" role.")
91)]
92pub struct SystemInfoCommand {}
93
94#[derive(Debug, Parser)]
95#[command(
96    about = "Reboot the device",
97    long_about = ex_format!("Reboot the device
98
99Requires authentication of a user in the \"{Administrator}\" role.")
100)]
101pub struct SystemRebootCommand {}
102
103#[derive(Debug, Parser)]
104#[command(
105    about = "Restore the device from a backup",
106    long_about = ex_format!("Restore the device from a backup
107
108The device may be in state \"{Operational}\" or \"{Unprovisioned}\".
109In both cases, the users and keys from the backup replace those on the device (if any).
110
111If the device is in state \"{Unprovisioned}\", any credentials provided for authentication are ignored, the system configuration
112(e.g. TLS certificate, unlock passphrase, etc.) from the backup is used as well, the device is rebooted and ends up in
113\"{Locked}\" state.
114
115If no new system time is provided, it is derived from the caller's system time.
116If no backup passphrase is provided specifically, it is prompted for interactively.
117
118Requires authentication of a system-wide user in the \"{Administrator}\" role only if the device is in \"{Operational}\" state.")
119)]
120pub struct SystemRestoreCommand {
121    #[arg(
122        env = "NETHSM_BACKUP_FILE",
123        help = "The path to a valid NetHSM backup file"
124    )]
125    pub input: PathBuf,
126
127    #[arg(
128        env = "NETHSM_BACKUP_PASSPHRASE_FILE",
129        help = "The path to a file containing the backup passphrase",
130        long,
131        short
132    )]
133    pub backup_passphrase_file: Option<PassphraseFile>,
134
135    #[arg(
136        env = "NETHSM_SYSTEM_TIME",
137        help = "The new system time for the device",
138        long_help = "The new system time for the device
139
140Must be provided as an ISO 8601 formatted UTC timestamp.",
141        long,
142        short
143    )]
144    pub system_time: Option<DateTime<Utc>>,
145}
146
147#[derive(Debug, Parser)]
148#[command(
149    about = "Shut down the device",
150    long_about = ex_format!("Shut down the device
151
152The device must be in state \"{Operational}\".
153
154Requires authentication of a system-wide user in the \"{Administrator}\" role.")
155)]
156pub struct SystemShutdownCommand {}
157
158#[derive(Debug, Parser)]
159#[command(
160    about = "Upload an update to the device",
161    long_about = ex_format!("Upload an update to the device
162
163Requires authentication of a user in the \"{Administrator}\" role.")
164)]
165pub struct SystemUploadUpdateCommand {
166    #[arg(env = "NETHSM_UPDATE_FILE", help = "The path to an update file")]
167    pub input: PathBuf,
168}
169
170#[derive(Debug, Parser)]
171#[command(
172    about = "Cancel an uploaded update on the device",
173    long_about = ex_format!("Cancel an uploaded update on the device
174
175The device must be in state \"{Operational}\" and an update file must have been uploaded first!
176
177Requires authentication of a system-wide user in the \"{Administrator}\" role.")
178)]
179pub struct SystemCancelUpdateCommand {}
180
181#[derive(Debug, Parser)]
182#[command(
183    about = "Commit an uploaded update on the device",
184    long_about = ex_format!("Commit an uploaded update on the device
185
186The device must be in state \"{Operational}\" and an update file must have been uploaded first!
187
188Requires authentication of a system-wide user in the \"{Administrator}\" role.")
189)]
190pub struct SystemCommitUpdateCommand {}
191
192#[derive(Debug, Parser)]
193#[command(
194    about = "Validate a backup file",
195    long_about = ex_format!("Validate a backup file
196
197Parse an encrypted backup file to ensure general properties.
198If a passphrase is provided, decrypting the backup file and validating its version number is attempted.
199This command exits with a non-zero exit code, if the file is corrupted, decryption or validation fails.
200
201Note: Backups are created using \"{BIN_NAME} system backup\"")
202)]
203pub struct SystemValidateBackupCommand {
204    #[arg(
205        env = "NETHSM_VALIDATE_BACKUP_PASSPHRASE_FILE",
206        help = "The path to a file containing the backup passphrase",
207        long,
208        short
209    )]
210    pub backup_passphrase_file: Option<PassphraseFile>,
211
212    #[arg(
213        env = "NETHSM_VALIDATE_BACKUP_FILE",
214        help = "The path to the backup file to validate"
215    )]
216    pub input: PathBuf,
217}