use clap::{Parser, Subcommand};
use expression_format::ex_format;
use nethsm::{ConnectionSecurity, Url, UserId, UserRole};
use strum::IntoEnumIterator;
use crate::passphrase_file::PassphraseFile;
#[derive(Debug, Subcommand)]
#[command(about = "Manage environments in the configuration file")]
pub enum EnvCommand {
#[command(subcommand)]
Add(EnvAddCommand),
#[command(subcommand)]
Delete(EnvDeleteCommand),
#[command(about = "List all items in the configuration file")]
List,
}
#[derive(Debug, Subcommand)]
#[command(
about = "Add a configuration item",
long_about = "Add a configuration item
Add a new device, or credentials for an existing one."
)]
pub enum EnvAddCommand {
Credentials(CredentialsAddCommand),
Device(DeviceAddCommand),
}
#[derive(Debug, Parser)]
#[command(
about = "Add credentials for a device in the configuration",
long_about = "Add credentials for a device in the configuration
By default credentials in the configuration file only contain user name and role.
In this scenario the passphrase of a user is prompted for interactively, once it is needed.
Optionally, it is possible to also persist a passphrase for a given user name to allow non-interactive use.
This use is discouraged as it persists the passphrase in an unencrypted configuration file."
)]
pub struct CredentialsAddCommand {
#[arg(
env = "NETHSM_USER_NAME",
help = "The name of the user on the target device"
)]
pub name: UserId,
#[arg(
env = "NETHSM_PASSPHRASE_FILE",
help = "The path to a file containing the passphrase",
long,
short
)]
pub passphrase_file: Option<PassphraseFile>,
#[arg(
env = "NETHSM_USER_ROLE",
help = "The optional role of the user on the target device",
long_help = format!("The optional role of the user on the target device
One of {:?} (defaults to \"{}\").", UserRole::iter().map(Into::into).collect::<Vec<&'static str>>(), UserRole::default())
)]
pub role: Option<UserRole>,
#[arg(
env = "NETHSM_WITH_PASSPHRASE",
help = "Whether to prompt for and store a passphrase for the user",
long_help = "Whether to prompt for and store a passphrase for the user
The passphrase is persisted in the configuration file. Use with caution!",
long,
short
)]
pub with_passphrase: bool,
}
#[derive(Debug, Parser)]
#[command(
about = "Add a device to the configuration",
long_about = "Add a device to the configuration
Device entries are added with a URL and settings for the TLS connection security.
For this command it is required to provide a label that identifies the device."
)]
pub struct DeviceAddCommand {
#[arg(env = "NETHSM_URL", help = "The URL of the device API")]
pub url: Url,
#[arg(
env = "NETHSM_TLS_SECURITY",
help = "The TLS connection security for the device",
long_help = ex_format!("The TLS connection security for the device
One of the following:
* \"{:?ConnectionSecurity::Unsafe}\": the TLS connection is not validated by authenticating the target host certificate
* \"{:?ConnectionSecurity::Native}\": the TLS connection is validated by authenticating the target host certificate against the caller's native system-wide certificate store
* the pinned SHA-256 checksum of the target host key (prefixed with \"sha256:\") is used to validate the target host certificate"),
)]
pub tls_security: ConnectionSecurity,
}
#[derive(Debug, Subcommand)]
#[command(
about = "Delete a configuration item",
long_about = "Delete a configuration item
Delete credentials for an existing device or a device."
)]
pub enum EnvDeleteCommand {
Credentials(CredentialsDeleteCommand),
Device(DeviceDeleteCommand),
}
#[derive(Debug, Parser)]
#[command(about = "Delete credentials for a device")]
pub struct CredentialsDeleteCommand {
#[arg(
env = "NETHSM_USER_NAME",
help = "The user name matching the credentials to be deleted"
)]
pub name: UserId,
}
#[derive(Debug, Parser)]
#[command(
about = "Delete a device",
long_about = "Delete a device from the configuration
For this command it is required to provide a label that identifies the device."
)]
pub struct DeviceDeleteCommand {}