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
}
}