#![forbid(unsafe_code)]
use super::scp_args::ScpAction;
use super::sftp_args::SftpAction;
use super::vps_action::VpsAction;
use super::SshAuthArgs;
use clap::{ArgAction, Subcommand, ValueHint};
use clap_complete::Shell;
use std::path::PathBuf;
const EXEC_USAGE_BLOCK: &str = "ssh-cli exec [OPTIONS] <VPS> <COMMAND>\n \
ssh-cli exec [OPTIONS] --use-active <COMMAND>\n \
ssh-cli exec [OPTIONS] --all|--hosts <LIST>|--tags <LIST> <COMMAND>";
const SUDO_EXEC_USAGE_BLOCK: &str = "ssh-cli sudo-exec [OPTIONS] <VPS> <COMMAND>\n \
ssh-cli sudo-exec [OPTIONS] --use-active <COMMAND>\n \
ssh-cli sudo-exec [OPTIONS] --all|--hosts <LIST>|--tags <LIST> <COMMAND>";
const SU_EXEC_USAGE_BLOCK: &str = "ssh-cli su-exec [OPTIONS] <VPS> <COMMAND>\n \
ssh-cli su-exec [OPTIONS] --use-active <COMMAND>\n \
ssh-cli su-exec [OPTIONS] --all|--hosts <LIST>|--tags <LIST> <COMMAND>";
const HEALTH_CHECK_USAGE: &str = "ssh-cli health-check [OPTIONS] <VPS_NAME>\n \
ssh-cli health-check [OPTIONS] --use-active\n \
ssh-cli health-check [OPTIONS] --all|--hosts <LIST>";
#[derive(Debug, Subcommand)]
pub enum Command {
Vps {
#[command(subcommand)]
action: VpsAction,
},
Connect {
name: String,
},
#[command(override_usage = EXEC_USAGE_BLOCK)]
Exec {
#[arg(long, action = ArgAction::SetTrue, conflicts_with_all = ["hosts", "tags"])]
all: bool,
#[arg(long, value_name = "LIST", conflicts_with_all = ["all", "tags"])]
hosts: Option<String>,
#[arg(long, value_name = "LIST", conflicts_with_all = ["all", "hosts"])]
tags: Option<String>,
#[arg(long = "use-active", action = ArgAction::SetTrue, conflicts_with_all = ["all", "hosts", "tags"])]
use_active: bool,
#[arg(required = true, num_args = 1..=2, value_names = ["VPS", "COMMAND"])]
target: Vec<String>,
#[arg(long = "step", value_name = "CMD", action = ArgAction::Append)]
steps: Vec<String>,
#[arg(from_global)]
json: bool,
#[command(flatten)]
auth: SshAuthArgs,
#[arg(long, value_name = "MS")]
timeout: Option<u64>,
#[arg(long)]
description: Option<String>,
},
#[command(override_usage = SUDO_EXEC_USAGE_BLOCK)]
SudoExec {
#[arg(long, action = ArgAction::SetTrue, conflicts_with_all = ["hosts", "tags"])]
all: bool,
#[arg(long, value_name = "LIST", conflicts_with_all = ["all", "tags"])]
hosts: Option<String>,
#[arg(long, value_name = "LIST", conflicts_with_all = ["all", "hosts"])]
tags: Option<String>,
#[arg(long = "use-active", action = ArgAction::SetTrue, conflicts_with_all = ["all", "hosts", "tags"])]
use_active: bool,
#[arg(required = true, num_args = 1..=2, value_names = ["VPS", "COMMAND"])]
target: Vec<String>,
#[arg(long = "step", value_name = "CMD", action = ArgAction::Append)]
steps: Vec<String>,
#[arg(from_global)]
json: bool,
#[command(flatten)]
auth: SshAuthArgs,
#[arg(
long,
alias = "sudoPassword",
alias = "sudo_password",
conflicts_with = "sudo_password_stdin"
)]
sudo_password: Option<String>,
#[arg(long, action = ArgAction::SetTrue)]
sudo_password_stdin: bool,
#[arg(long, value_name = "MS")]
timeout: Option<u64>,
#[arg(long)]
description: Option<String>,
},
#[command(override_usage = SU_EXEC_USAGE_BLOCK)]
SuExec {
#[arg(long, action = ArgAction::SetTrue, conflicts_with_all = ["hosts", "tags"])]
all: bool,
#[arg(long, value_name = "LIST", conflicts_with_all = ["all", "tags"])]
hosts: Option<String>,
#[arg(long, value_name = "LIST", conflicts_with_all = ["all", "hosts"])]
tags: Option<String>,
#[arg(long = "use-active", action = ArgAction::SetTrue, conflicts_with_all = ["all", "hosts", "tags"])]
use_active: bool,
#[arg(required = true, num_args = 1..=2, value_names = ["VPS", "COMMAND"])]
target: Vec<String>,
#[arg(long = "step", value_name = "CMD", action = ArgAction::Append)]
steps: Vec<String>,
#[arg(from_global)]
json: bool,
#[command(flatten)]
auth: SshAuthArgs,
#[arg(
long,
alias = "suPassword",
alias = "su_password",
conflicts_with = "su_password_stdin"
)]
su_password: Option<String>,
#[arg(long, action = ArgAction::SetTrue)]
su_password_stdin: bool,
#[arg(long, value_name = "MS")]
timeout: Option<u64>,
#[arg(long)]
description: Option<String>,
},
Scp {
#[command(subcommand)]
action: ScpAction,
},
Sftp {
#[command(subcommand)]
action: SftpAction,
},
Tunnel {
vps_name: String,
local_port: u16,
remote_host: Option<String>,
#[arg(value_parser = clap::value_parser!(u16).range(0..=65535))]
remote_port: Option<u16>,
#[arg(long, action = ArgAction::SetTrue, conflicts_with_all = ["reverse", "remote_socket"])]
socks5: bool,
#[arg(long, value_name = "PATH", conflicts_with_all = ["reverse", "socks5"])]
remote_socket: Option<String>,
#[arg(long, action = ArgAction::SetTrue, conflicts_with_all = ["socks5", "remote_socket"])]
reverse: bool,
#[arg(long, value_name = "MS")]
timeout_ms: u64,
#[command(flatten)]
auth: SshAuthArgs,
#[arg(from_global)]
json: bool,
#[arg(
long,
default_value = crate::constants::DEFAULT_TUNNEL_BIND_ADDR,
value_name = "ADDR",
value_parser = clap::value_parser!(std::net::IpAddr)
)]
bind: std::net::IpAddr,
#[arg(long, action = ArgAction::SetTrue)]
i_accept_network_exposure: bool,
},
#[command(override_usage = HEALTH_CHECK_USAGE)]
HealthCheck {
#[arg(conflicts_with_all = ["all", "hosts", "use_active"])]
vps_name: Option<String>,
#[arg(long, action = ArgAction::SetTrue, conflicts_with = "hosts")]
all: bool,
#[arg(long, value_name = "LIST", conflicts_with = "all")]
hosts: Option<String>,
#[arg(long = "use-active", action = ArgAction::SetTrue, conflicts_with_all = ["all", "hosts"])]
use_active: bool,
#[arg(from_global)]
json: bool,
#[command(flatten)]
auth: SshAuthArgs,
#[arg(long, value_name = "MS")]
timeout: Option<u64>,
},
Secrets {
#[command(subcommand)]
action: SecretsAction,
},
Completions {
#[arg(value_enum)]
shell: Shell,
},
Commands {
#[arg(from_global)]
json: bool,
},
Schema {
name: Option<String>,
#[arg(from_global)]
json: bool,
},
Doctor {
#[arg(from_global)]
json: bool,
#[arg(long, action = ArgAction::SetTrue)]
probe_ssh: bool,
#[arg(long, value_name = "LIST")]
hosts: Option<String>,
},
Locale {
#[arg(from_global)]
json: bool,
#[command(subcommand)]
action: Option<LocaleAction>,
},
Tls {
#[arg(from_global)]
json: bool,
#[command(subcommand)]
action: TlsAction,
},
}
#[derive(Debug, Subcommand)]
pub enum TlsAction {
Provider,
Paths,
Mtls {
#[command(subcommand)]
action: TlsMtlsAction,
},
Acme {
#[command(subcommand)]
action: TlsAcmeAction,
},
}
#[derive(Debug, Subcommand)]
pub enum TlsMtlsAction {
List,
Import {
#[arg(long)]
name: String,
#[arg(long, value_name = "PATH", value_hint = ValueHint::FilePath)]
cert: PathBuf,
#[arg(long, value_name = "PATH", value_hint = ValueHint::FilePath)]
key: PathBuf,
},
Show {
name: String,
},
Remove {
name: String,
},
}
#[derive(Debug, Subcommand)]
pub enum TlsAcmeAction {
Account {
#[command(subcommand)]
action: TlsAcmeAccountAction,
},
Issue {
#[arg(long)]
domain: String,
#[arg(long, action = ArgAction::SetTrue)]
staging: bool,
#[arg(long, action = ArgAction::SetTrue)]
print_challenge: bool,
},
Complete {
#[arg(long)]
domain: String,
},
Status {
#[arg(long)]
domain: Option<String>,
},
List,
}
#[derive(Debug, Subcommand)]
pub enum TlsAcmeAccountAction {
Create {
#[arg(long, action = ArgAction::SetTrue)]
staging: bool,
#[arg(long = "contact", value_name = "URL", action = ArgAction::Append, required = true, num_args = 1..)]
contact: Vec<String>,
#[arg(long, action = ArgAction::SetTrue)]
force: bool,
},
Show,
}
#[derive(Debug, Subcommand)]
pub enum LocaleAction {
Show,
Set {
#[arg(value_name = "LOCALE", value_parser = crate::locale::parse_lang_cli_arg)]
lang: String,
},
Clear,
}
#[derive(Debug, Subcommand)]
pub enum SecretsAction {
Status {
#[arg(from_global)]
json: bool,
},
Init {
#[arg(long)]
keyring: bool,
#[arg(long)]
force: bool,
#[arg(from_global)]
json: bool,
},
Reencrypt {
#[arg(from_global)]
json: bool,
},
}