1use clap::{Parser, Subcommand};
2use expression_format::ex_format;
3use nethsm::{ConnectionSecurity, Url, UserId, UserRole};
4use strum::IntoEnumIterator;
5
6use crate::passphrase_file::PassphraseFile;
7
8#[derive(Debug, Subcommand)]
10#[command(about = "Manage environments in the configuration file")]
11pub enum EnvCommand {
12 #[command(subcommand)]
14 Add(EnvAddCommand),
15
16 #[command(subcommand)]
18 Delete(EnvDeleteCommand),
19
20 #[command(about = "List all items in the configuration file")]
22 List,
23}
24
25#[derive(Debug, Subcommand)]
27#[command(
28 about = "Add a configuration item",
29 long_about = "Add a configuration item
30
31Add a new device, or credentials for an existing one."
32)]
33pub enum EnvAddCommand {
34 Credentials(CredentialsAddCommand),
36 Device(DeviceAddCommand),
38}
39
40#[derive(Debug, Parser)]
41#[command(
42 about = "Add credentials for a device in the configuration",
43 long_about = "Add credentials for a device in the configuration
44
45By default credentials in the configuration file only contain user name and role.
46In this scenario the passphrase of a user is prompted for interactively, once it is needed.
47
48Optionally, it is possible to also persist a passphrase for a given user name to allow non-interactive use.
49This use is discouraged as it persists the passphrase in an unencrypted configuration file."
50)]
51pub struct CredentialsAddCommand {
52 #[arg(
53 env = "NETHSM_USER_NAME",
54 help = "The name of the user on the target device"
55 )]
56 pub name: UserId,
57
58 #[arg(
59 env = "NETHSM_PASSPHRASE_FILE",
60 help = "The path to a file containing the passphrase",
61 long,
62 short
63 )]
64 pub passphrase_file: Option<PassphraseFile>,
65
66 #[arg(
67 env = "NETHSM_USER_ROLE",
68 help = "The optional role of the user on the target device",
69 long_help = format!("The optional role of the user on the target device
70
71One of {:?} (defaults to \"{}\").", UserRole::iter().map(Into::into).collect::<Vec<&'static str>>(), UserRole::default())
72 )]
73 pub role: Option<UserRole>,
74
75 #[arg(
76 env = "NETHSM_WITH_PASSPHRASE",
77 help = "Whether to prompt for and store a passphrase for the user",
78 long_help = "Whether to prompt for and store a passphrase for the user
79
80The passphrase is persisted in the configuration file. Use with caution!",
81 long,
82 short
83 )]
84 pub with_passphrase: bool,
85}
86
87#[derive(Debug, Parser)]
88#[command(
89 about = "Add a device to the configuration",
90 long_about = "Add a device to the configuration
91
92Device entries are added with a URL and settings for the TLS connection security.
93
94For this command it is required to provide a label that identifies the device."
95)]
96pub struct DeviceAddCommand {
97 #[arg(env = "NETHSM_URL", help = "The URL of the device API")]
98 pub url: Url,
99
100 #[arg(
101 env = "NETHSM_TLS_SECURITY",
102 help = "The TLS connection security for the device",
103 long_help = ex_format!("The TLS connection security for the device
104
105One of the following:
106* \"{:?ConnectionSecurity::Unsafe}\": the TLS connection is not validated by authenticating the target host certificate
107* \"{:?ConnectionSecurity::Native}\": the TLS connection is validated by authenticating the target host certificate against the caller's native system-wide certificate store
108* the pinned SHA-256 checksum of the target host key (prefixed with \"sha256:\") is used to validate the target host certificate"),
109 )]
110 pub tls_security: ConnectionSecurity,
111}
112
113#[derive(Debug, Subcommand)]
115#[command(
116 about = "Delete a configuration item",
117 long_about = "Delete a configuration item
118
119Delete credentials for an existing device or a device."
120)]
121pub enum EnvDeleteCommand {
122 Credentials(CredentialsDeleteCommand),
124 Device(DeviceDeleteCommand),
126}
127
128#[derive(Debug, Parser)]
129#[command(about = "Delete credentials for a device")]
130pub struct CredentialsDeleteCommand {
131 #[arg(
132 env = "NETHSM_USER_NAME",
133 help = "The user name matching the credentials to be deleted"
134 )]
135 pub name: UserId,
136}
137
138#[derive(Debug, Parser)]
139#[command(
140 about = "Delete a device",
141 long_about = "Delete a device from the configuration
142
143For this command it is required to provide a label that identifies the device."
144)]
145pub struct DeviceDeleteCommand {}