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