trifid/tfcli/src/main.rs

181 lines
5.4 KiB
Rust
Raw Normal View History

2023-06-16 00:49:06 +00:00
use std::error::Error;
use std::fs;
use clap::{Parser, Subcommand};
use ipnet::Ipv4Net;
use url::Url;
use crate::account::account_main;
use crate::network::network_main;
use crate::org::org_main;
2023-06-16 02:00:09 +00:00
use crate::role::role_main;
2023-06-16 00:49:06 +00:00
pub mod account;
pub mod api;
pub mod network;
pub mod org;
2023-06-16 02:00:09 +00:00
pub mod role;
2023-06-16 00:49:06 +00:00
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub struct Args {
#[command(subcommand)]
command: Commands,
#[clap(short, long, env = "TFCLI_SERVER")]
/// The base URL of your trifid-api instance. Defaults to the value in $XDG_CONFIG_HOME/tfcli-server-url.conf or the TFCLI_SERVER environment variable.
server: Option<Url>
}
#[derive(Subcommand, Debug)]
pub enum Commands {
/// Manage your trifid account
Account {
#[command(subcommand)]
command: AccountCommands
},
/// Manage the networks associated with your trifid account
Network {
#[command(subcommand)]
command: NetworkCommands
},
/// Manage the organization associated with your trifid account
Org {
#[command(subcommand)]
command: OrgCommands
2023-06-16 02:00:09 +00:00
},
/// Manage the roles associated with your trifid organization
Role {
#[command(subcommand)]
command: RoleCommands
2023-06-16 00:49:06 +00:00
}
}
#[derive(Subcommand, Debug)]
pub enum AccountCommands {
/// Create a new trifid account on the designated server
Create {
#[clap(short, long)]
email: String
},
/// Log in to your account with a magic-link token acquired via email or the trifid-api logs.
MagicLink {
#[clap(short, long)]
magic_link_token: String
},
/// Create a new TOTP authenticator on this account to enable authorizing with 2fa and performing all management tasks.
MfaSetup {},
/// Finish creating a new TOTP authenticator by inputting the code shown on your authenticator app.
MfaSetupFinish {
#[clap(short, long)]
code: String,
#[clap(short, long)]
token: String
},
/// Create a new short-lived authentication token by inputting the code shown on your authenticator app.
Mfa {
#[clap(short, long)]
code: String
}
}
#[derive(Subcommand, Debug)]
pub enum NetworkCommands {
/// List all networks associated with your trifid account.
List {},
/// Lookup a specific network by ID.
Lookup {
#[clap(short, long)]
id: String
}
}
#[derive(Subcommand, Debug)]
pub enum OrgCommands {
/// Create an organization on your trifid-api server. NOTE: This command ONLY works on trifid-api servers. It will NOT work on original DN servers.
Create {
#[clap(short, long)]
cidr: Ipv4Net
}
}
2023-06-16 02:00:09 +00:00
#[derive(Subcommand, Debug)]
pub enum RoleCommands {
/// Create a role on your organization
Create {
#[clap(short, long)]
name: String,
#[clap(short, long)]
description: String,
/// A JSON string containing the firewall rules to add to this host
#[clap(short, long)]
rules_json: String
},
/// List all roles attached to your organization
List {},
/// Lookup a specific role by it's ID
Lookup {
#[clap(short, long)]
id: String
},
/// Delete a specific role by it's ID
Delete {
#[clap(short, long)]
id: String
},
/// Update a specific role by it's ID. Warning: any data not provided in this update will be removed - include all data you wish to remain
Update {
#[clap(short, long)]
id: String,
#[clap(short, long)]
description: String,
/// A JSON string containing the firewall rules to add to this host
#[clap(short, long)]
rules_json: String
}
}
2023-06-16 00:49:06 +00:00
#[tokio::main]
async fn main() {
match main2().await {
Ok(_) => (),
Err(e) => {
eprintln!("There was an error during execution: {}", e);
std::process::exit(1);
}
}
}
async fn main2() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
// find server
let server;
if let Some(srv) = args.server {
server = srv; // Environment variable or CLI takes precedence over config file
} else {
let srv_url_file = dirs::config_dir().unwrap().join("tfcli-server-url.conf");
if !srv_url_file.exists() {
eprintln!("[error] no server URL available: '-s/--server' not provided, TFCLI_SERVER not set, and {} does not exist", srv_url_file.display());
eprintln!("[error] please set a server url via any of these mechanisms and try again");
std::process::exit(1);
}
let url_s = fs::read_to_string(&srv_url_file)?;
let url = match Url::parse(&url_s) {
Ok(u) => u,
Err(e) => {
eprintln!("[error] unable to parse the URL in {}", srv_url_file.display());
eprintln!("[error] urlparse returned error '{}'", e);
eprintln!("[error] please correct the error and try again");
std::process::exit(1);
}
};
server = url;
}
match args.command {
Commands::Account { command } => account_main(command, server).await,
Commands::Network { command } => network_main(command, server).await,
2023-06-16 02:00:09 +00:00
Commands::Org { command } => org_main(command, server).await,
Commands::Role { command } => role_main(command, server).await
2023-06-16 00:49:06 +00:00
}
}