use clap::{Parser, Subcommand, ValueEnum};
#[derive(ValueEnum, Clone, Copy, Debug)]
pub enum LangArg {
En,
Ru
}
#[derive(ValueEnum, Clone, Copy, Debug)]
pub enum ShellArg {
Bash,
Zsh,
Fish,
Powershell,
Elvish,
Nushell
}
#[derive(Parser, Debug)]
#[command(
name = "twc-rs",
version,
about = "Timeweb Cloud CLI — manage servers, SSH keys, and projects"
)]
pub struct Cli {
#[arg(
short,
long,
global = true,
default_value = "table",
env = "TWC_OUTPUT"
)]
pub format: String,
#[arg(short, long, global = true, env = "TWC_TOKEN")]
pub token: Option<String>,
#[arg(long, global = true, env = "TWC_PROFILE")]
pub profile: Option<String>,
#[command(subcommand)]
pub command: Commands
}
#[derive(Subcommand, Debug)]
pub enum Commands {
#[command(subcommand)]
Server(ServerCommands),
#[command(subcommand)]
Ssh(SshCommands),
#[command(subcommand)]
Project(ProjectCommands),
#[command(subcommand)]
Database(DatabaseCommands),
#[command(subcommand)]
S3(S3Commands),
#[command(subcommand)]
Kubernetes(KubernetesCommands),
#[command(subcommand)]
Registry(RegistryCommands),
#[command(subcommand)]
Balancer(BalancerCommands),
#[command(subcommand)]
Domain(DomainCommands),
#[command(subcommand)]
Firewall(FirewallCommands),
#[command(subcommand)]
Apps(AppsCommands),
#[command(subcommand)]
Image(ImageCommands),
#[command(subcommand)]
Ip(IpCommands),
#[command(subcommand)]
Vpc(VpcCommands),
#[command(subcommand)]
Account(AccountCommands),
#[command(subcommand)]
Config(ConfigCommands),
#[command(subcommand)]
Auth(AuthCommands),
Dashboard {
#[arg(short, long, default_value_t = 5)]
interval: u64
},
Completions {
#[arg(value_enum)]
shell: ShellArg
}
}
#[derive(Subcommand, Debug)]
pub enum ServerCommands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: i32
},
Delete {
#[arg(long)]
id: i32
},
Reboot {
#[arg(long)]
id: i32
},
Start {
#[arg(long)]
id: i32
},
Shutdown {
#[arg(long)]
id: i32
},
Clone {
#[arg(long)]
id: i32
},
ResetPassword {
#[arg(long)]
id: i32
},
ListPresets,
ListOs,
ListSoftware,
ListConfigurators,
Disk {
#[arg(long)]
id: i32
},
Ip {
#[arg(long)]
id: i32
},
History {
#[arg(long)]
id: i32
},
SetNatMode {
#[arg(long)]
id: i32,
#[arg(long)]
nat_mode: String
},
SetBootMode {
#[arg(long)]
id: i32,
#[arg(long)]
boot_mode: String
},
Resize {
#[arg(long)]
id: i32,
#[arg(long)]
preset_id: i32
},
Reinstall {
#[arg(long)]
id: i32,
#[arg(long)]
os_id: i32
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
preset_id: i32,
#[arg(long)]
os_id: i32,
#[arg(long)]
comment: Option<String>,
#[arg(long = "ssh-key")]
ssh_key: Vec<i32>,
#[arg(long)]
project_id: Option<i32>,
#[arg(long)]
availability_zone: Option<String>
},
Set {
#[arg(long)]
id: i32,
#[arg(long)]
name: Option<String>,
#[arg(long)]
comment: Option<String>
},
BackupList {
#[arg(long)]
id: i32
},
BackupCreate {
#[arg(long)]
id: i32,
#[arg(long)]
comment: Option<String>
}
}
#[derive(Subcommand, Debug)]
pub enum SshCommands {
List,
Add {
#[arg(long)]
name: String,
#[arg(long)]
file: Option<String>,
#[arg(long)]
default: bool
},
Delete {
#[arg(long)]
id: i32
},
Info {
#[arg(long)]
id: i32
},
Edit {
#[arg(long)]
id: i32,
#[arg(long)]
name: Option<String>,
#[arg(long)]
default: Option<bool>
},
Attach {
#[arg(long)]
server: i32,
#[arg(long = "key")]
key: Vec<i32>
},
Detach {
#[arg(long)]
server: i32,
#[arg(long = "key")]
key: i32
}
}
#[derive(Subcommand, Debug)]
pub enum ProjectCommands {
List,
Create {
#[arg(long)]
name: String,
#[arg(long)]
description: Option<String>
},
Delete {
#[arg(long)]
id: i32
},
Set {
#[arg(long)]
id: i32,
#[arg(long)]
name: Option<String>,
#[arg(long)]
description: Option<String>
},
Resources {
#[arg(long)]
id: i32
}
}
#[derive(Subcommand, Debug)]
pub enum DatabaseCommands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: i32
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
type_: String,
#[arg(short = 'p', long)]
preset_id: i32
},
Delete {
#[arg(long)]
id: i32
},
Update {
#[arg(long)]
id: i32,
#[arg(long)]
name: Option<String>
},
Restart {
#[arg(long)]
id: i32
},
BackupList {
#[arg(long)]
id: i32
},
BackupCreate {
#[arg(long)]
id: i32
},
UserList {
#[arg(long)]
id: i32
},
UserCreate {
#[arg(long)]
db_id: i32,
#[arg(long)]
login: String,
#[arg(long)]
password: String
},
UserDelete {
#[arg(long)]
db_id: i32,
#[arg(long)]
user_name: String
},
PresetList,
ListTypes,
ListInstances {
#[arg(long)]
id: i32
}
}
#[derive(Subcommand, Debug)]
pub enum ConfigCommands {
Show,
SetToken {
#[arg(long)]
token: String,
#[arg(long)]
profile: Option<String>
},
Profiles,
SetLanguage {
#[arg(value_enum)]
language: LangArg
}
}
#[derive(Subcommand, Debug)]
pub enum AuthCommands {
Flow,
Status,
Logout,
Token {
#[arg(long)]
token: String
}
}
#[derive(Subcommand, Debug)]
pub enum S3Commands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: i32
},
Create {
#[arg(long)]
name: String,
#[arg(short = 'p', long)]
preset_id: Option<f64>
},
Delete {
#[arg(long)]
id: i32
},
Update {
#[arg(long)]
id: i32,
#[arg(long)]
description: Option<String>
},
UserList {
#[arg(long)]
id: i32
},
UserUpdate {
#[arg(long)]
user_id: i32
},
Transfer {
#[arg(long)]
target_id: Option<i32>
},
SubdomainList {
#[arg(long)]
id: i32
},
SubdomainAdd {
#[arg(long)]
id: i32,
#[arg(long)]
subdomain: String
},
SubdomainDelete {
#[arg(long)]
id: i32,
#[arg(long)]
subdomain: String
},
PresetList,
Genconfig {
#[arg(long)]
id: i32
}
}
#[derive(Subcommand, Debug)]
pub enum KubernetesCommands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: i32
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
type_: String
},
Delete {
#[arg(long)]
id: i32
},
Update {
#[arg(long)]
id: i32,
#[arg(long)]
name: Option<String>
},
NodegroupList {
#[arg(long)]
id: i32
},
NodegroupCreate {
#[arg(long)]
id: i32,
#[arg(long)]
name: String
},
NodegroupDelete {
#[arg(long)]
id: i32,
#[arg(long)]
group_id: i32
},
NodeList {
#[arg(long)]
id: i32
},
AddonList {
#[arg(long)]
id: i32
},
AddonInstall {
#[arg(long)]
id: i32,
#[arg(long)]
addon_name: String
},
AddonDelete {
#[arg(long)]
id: i32,
#[arg(long)]
addon_name: String
},
PresetList,
VersionList,
NetworkDrivers,
Kubeconfig {
#[arg(long)]
id: i32
},
#[command(hide = true)]
Resources {
#[arg(long)]
id: i32
}
}
#[derive(Subcommand, Debug)]
pub enum RegistryCommands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: i32
},
Create {
#[arg(long)]
name: String
},
Delete {
#[arg(long)]
id: i32
},
Update {
#[arg(long)]
id: i32,
#[arg(long)]
description: Option<String>
},
RepoList {
#[arg(long)]
id: i32
},
PresetList
}
#[derive(Subcommand, Debug)]
pub enum BalancerCommands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: i32
},
Create {
#[arg(long)]
name: String
},
Delete {
#[arg(long)]
id: i32
},
Update {
#[arg(long)]
id: i32,
#[arg(long)]
name: Option<String>
},
RuleList {
#[arg(long)]
id: i32
},
RuleCreate {
#[arg(long)]
id: i32
},
RuleDelete {
#[arg(long)]
id: i32,
#[arg(long)]
rule_id: i32
},
IpList {
#[arg(long)]
id: i32
},
IpAdd {
#[arg(long)]
id: i32,
#[arg(long)]
ip: String
},
IpRemove {
#[arg(long)]
id: i32,
#[arg(long)]
ip: String
},
PresetList
}
#[derive(Subcommand, Debug)]
pub enum DomainCommands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: String
},
Check {
#[arg(long)]
domain: String
},
Add {
#[arg(long)]
domain: String
},
Delete {
#[arg(long)]
id: String
},
DnsList {
#[arg(long)]
id: String
},
DnsAdd {
#[arg(long)]
id: String,
#[arg(long)]
record_type: String,
#[arg(long)]
value: String
},
DnsDelete {
#[arg(long)]
id: String,
#[arg(long)]
record_id: i32
},
DnsUpdate {
#[arg(long)]
id: String,
#[arg(long)]
record_id: i32,
#[arg(long)]
record_type: String,
#[arg(long)]
value: String
},
NsList {
#[arg(long)]
id: String
},
NsUpdate {
#[arg(long)]
id: String,
#[arg(short = '1', long)]
ns1: String,
#[arg(short = '2', long)]
ns2: String
},
SubdomainList {
#[arg(long)]
id: String
},
SubdomainAdd {
#[arg(long)]
id: String,
#[arg(long)]
name: String
},
SubdomainDelete {
#[arg(long)]
id: String,
#[arg(long)]
name: String
},
RequestList,
TldList,
AutoProlong {
#[arg(long)]
id: String,
#[arg(long)]
enabled: bool
}
}
#[derive(Subcommand, Debug)]
pub enum FirewallCommands {
List {
#[arg(long)]
limit: Option<i32>,
#[arg(long)]
offset: Option<i32>
},
Info {
#[arg(long)]
id: String
},
Create {
#[arg(long)]
name: String
},
Delete {
#[arg(long)]
id: String
},
Update {
#[arg(long)]
id: String,
#[arg(long)]
name: Option<String>
},
RuleList {
#[arg(long)]
id: String
},
RuleCreate {
#[arg(long)]
id: String
},
RuleDelete {
#[arg(long)]
id: String,
#[arg(long)]
rule_id: String
},
ResourceList {
#[arg(long)]
id: String
},
ResourceAdd {
#[arg(long)]
id: String,
#[arg(long)]
resource_id: String
},
ResourceRemove {
#[arg(long)]
id: String,
#[arg(long)]
resource_id: String
}
}
#[cfg(test)]
mod tests;
#[derive(Subcommand, Debug)]
pub enum AppsCommands {
List,
Info {
#[arg(long)]
id: String
},
Delete {
#[arg(long)]
id: String
},
ListPresets,
ListVcsProviders,
ListRepositories {
#[arg(long)]
provider_id: String
},
Create(Box<AppCreateArgs>)
}
#[derive(clap::Args, Debug)]
pub struct AppCreateArgs {
#[arg(long)]
pub name: String,
#[arg(long)]
pub comment: Option<String>,
#[arg(long)]
pub provider_id: String,
#[arg(long)]
pub repository_id: String,
#[arg(long)]
pub preset_id: i64,
#[arg(long = "type")]
pub app_type: String,
#[arg(long)]
pub framework: String,
#[arg(long, default_value = "main")]
pub branch: String,
#[arg(long)]
pub commit_sha: Option<String>,
#[arg(long)]
pub build_cmd: Option<String>,
#[arg(long)]
pub run_cmd: Option<String>,
#[arg(long)]
pub index_dir: Option<String>,
#[arg(long)]
pub auto_deploy: bool,
#[arg(long)]
pub project_id: Option<i64>
}
#[derive(Subcommand, Debug)]
pub enum ImageCommands {
List,
Info {
#[arg(long)]
id: String
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
location: String
},
Set {
#[arg(long)]
id: String,
#[arg(long)]
name: Option<String>
},
Delete {
#[arg(long)]
id: String
},
Upload {
#[arg(long)]
id: String,
#[arg(long)]
file: String
}
}
#[derive(Subcommand, Debug)]
pub enum IpCommands {
List,
Info {
#[arg(long)]
id: String
},
Create {
#[arg(long)]
availability_zone: String
},
Attach {
#[arg(long)]
id: String,
#[arg(long)]
resource_id: i32
},
Detach {
#[arg(long)]
id: String
},
Set {
#[arg(long)]
id: String,
#[arg(long)]
comment: Option<String>
},
Delete {
#[arg(long)]
id: String
}
}
#[derive(Subcommand, Debug)]
pub enum VpcCommands {
List,
Info {
#[arg(long)]
id: String
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
subnet_v4: String,
#[arg(long)]
location: String
},
Set {
#[arg(long)]
id: String,
#[arg(long)]
name: Option<String>,
#[arg(long)]
description: Option<String>
},
Ports {
#[arg(long)]
id: String
},
Delete {
#[arg(long)]
id: String
}
}
#[derive(Subcommand, Debug)]
pub enum AccountCommands {
Show,
Access
}