use anyhow::Result;
use clap::CommandFactory;
use clap::{Parser, Subcommand};
use clap_complete::{Shell, generate};
use rnaapi::NaClient;
use rnaapi::config::Settings;
use rnaapi::endpoints;
use rnaapi::{EndpointGetAll, EndpointGetArgs, EndpointGetOne};
#[tokio::main]
async fn main() -> Result<()> {
let settings = Settings::new()?;
let mut ssh_keyid: u32 = 0;
let mut display_count: usize = 0;
let mut loc_mbpkgid: u32 = 0;
let mut loc_zoneid: u32 = 0;
let mut command: &str = "default";
let cli = Cli::parse();
match &cli.cmd {
Some(Commands::GenerateCompletions { shell }) => {
let mut app = Cli::command();
let appclone = app.clone();
generate(
*shell,
&mut app,
appclone.get_name().to_string(),
&mut std::io::stdout(),
);
}
Some(Commands::Get { cmd }) => match cmd {
GetCommands::Server { id } => {
if *id >= 1 {
loc_mbpkgid = *id;
command = "server";
} else {
command = "server";
}
}
GetCommands::Dns { id } => {
if *id >= 1 {
loc_zoneid = *id;
command = "dns";
} else {
command = "dns";
}
}
GetCommands::Ssh { id } => {
if *id >= 1 {
ssh_keyid = *id;
command = "ssh";
} else {
command = "ssh";
}
}
GetCommands::Invoice { count } => {
display_count = *count;
command = "invoice";
}
GetCommands::Location {} => {
command = "location";
}
GetCommands::Image {} => {
command = "image";
}
GetCommands::Account {} => {
command = "account";
}
},
_ => {}
}
let na_client = NaClient::new(settings.api_key, settings.api_url).await;
if command == "server" {
if loc_mbpkgid > 0 {
let (srv, jobs, ipv4s, ipv6s, stat) = tokio::join!(
endpoints::Server::get_one(
&na_client,
EndpointGetArgs::OneInt(loc_mbpkgid)
),
endpoints::SrvJob::get_all(
&na_client,
EndpointGetArgs::OneInt(loc_mbpkgid)
),
endpoints::IPv4::get_all(
&na_client,
EndpointGetArgs::OneInt(loc_mbpkgid)
),
endpoints::IPv6::get_all(
&na_client,
EndpointGetArgs::OneInt(loc_mbpkgid)
),
endpoints::SrvStatus::get_one(
&na_client,
EndpointGetArgs::OneInt(loc_mbpkgid)
),
);
println!(
"Package: {}, fqdn: {}, mbpkgid: {}",
srv.clone().unwrap().domu_package,
srv.clone().unwrap().fqdn,
srv.clone().unwrap().mbpkgid
);
println!();
for job in jobs.unwrap() {
println!(
"Inserted: {}, Status: {}, command: {}",
job.ts_insert, job.status, job.command
);
}
println!();
for ipv4 in ipv4s.unwrap() {
println!(
"Reverse: {}, IP: {}, Gateway: {}",
ipv4.reverse, ipv4.ip, ipv4.gateway
);
}
println!();
for ipv6 in ipv6s.unwrap() {
println!(
"Reverse: {}, IP: {}, Gateway: {}",
ipv6.reverse, ipv6.ip, ipv6.gateway
);
}
println!();
println!("Status: {}", stat.unwrap().status);
} else {
let srvrs =
endpoints::Server::get_all(&na_client, EndpointGetArgs::NoArgs)
.await?;
for srvr in srvrs {
println!("ID: {}, fqdn: {}", srvr.mbpkgid, srvr.fqdn);
}
}
} else if command == "dns" {
if loc_zoneid > 0 {
println!();
let zone = endpoints::Zone::get_one(
&na_client,
EndpointGetArgs::OneInt(loc_zoneid),
)
.await?;
println!("Zone: {}", zone.name);
let soa = zone.soa.unwrap();
println!("SOA: {}", soa.primary);
let recs = zone.records.unwrap();
println!("1st Record: {}", recs[0].name);
let nsrecs = zone.ns.unwrap();
println!("1st NS: {}", nsrecs[0].name)
} else {
println!();
let zones =
endpoints::Zone::get_all(&na_client, EndpointGetArgs::NoArgs)
.await?;
for zone in zones {
println!(
"ID: {}, Size: {}, Name: {}",
zone.id, zone.name, zone.zone_type
);
}
}
} else if command == "ssh" {
if ssh_keyid > 0 {
let sshkey = endpoints::SSHKeys::get_one(
&na_client,
EndpointGetArgs::OneInt(ssh_keyid),
)
.await?;
println!();
println!(
"ID: {}, Key: {}, Fingerprint: {}",
sshkey.id, sshkey.name, sshkey.fingerprint
);
} else {
let keys = endpoints::SSHKeys::get_all(
&na_client,
EndpointGetArgs::NoArgs,
)
.await?;
println!();
for sshkey in keys {
println!(
"ID: {}, Key: {}, Fingerprint: {}",
sshkey.id, sshkey.name, sshkey.fingerprint
);
}
}
} else if command == "location" {
let locs =
endpoints::Location::get_all(&na_client, EndpointGetArgs::NoArgs)
.await?;
println!();
for loc in locs {
println!(
"ID: {}, Name: {}, Continent: {}",
loc.id, loc.name, loc.continent
);
}
} else if command == "account" {
let deets =
endpoints::Details::get_one(&na_client, EndpointGetArgs::NoArgs)
.await?;
println!();
println!(
"FullName: {:?}, Address: {:?}, {:?} {:?} {:?}",
deets.fullname,
deets.address1,
deets.city,
deets.state,
deets.postcode
);
} else if command == "image" {
let imgs =
endpoints::Image::get_all(&na_client, EndpointGetArgs::NoArgs)
.await?;
println!();
for img in imgs {
println!(
"ID: {}, Size: {}, Name: {}",
img.id,
img.size.unwrap_or("null".to_owned()),
img.os.unwrap_or("null".to_owned())
);
}
println!();
} else if command == "invoice" {
let invoices =
endpoints::Invoices::get_all(&na_client, EndpointGetArgs::NoArgs)
.await?;
for invoice in invoices.iter().take(display_count) {
println!("ID: {}, Status: {}", invoice.id, invoice.status);
}
}
Ok(())
}
#[derive(Parser, Debug)]
#[command(version, about)]
struct Cli {
#[command(subcommand)]
cmd: Option<Commands>,
}
#[derive(Subcommand, Debug)]
enum Commands {
Get {
#[command(subcommand)]
cmd: GetCommands,
},
GenerateCompletions { shell: Shell },
}
#[derive(Subcommand, Debug)]
enum GetCommands {
Server {
#[arg(short, long, default_value_t = 0)]
id: u32,
},
Dns {
#[arg(short, long, default_value_t = 0)]
id: u32,
},
Ssh {
#[arg(short, long, default_value_t = 0)]
id: u32,
},
Invoice {
#[arg(short, long, default_value_t = 5)]
count: usize,
},
Location {},
Image {},
Account {},
}