diff --git a/Cargo.lock b/Cargo.lock index 0ad360f..e27538c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2721,7 +2721,7 @@ dependencies = [ [[package]] name = "tfcli" -version = "0.2.1" +version = "0.3.0" dependencies = [ "clap", "comfy-table", diff --git a/tfcli/Cargo.toml b/tfcli/Cargo.toml index e968add..eb8f473 100644 --- a/tfcli/Cargo.toml +++ b/tfcli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tfcli" -version = "0.3.0" +version = "0.3.1" edition = "2021" description = "Command-line client for managing trifid-api" license = "GPL-3.0-or-later" diff --git a/tfcli/src/host.rs b/tfcli/src/host.rs index 2f8d68d..e0d2398 100644 --- a/tfcli/src/host.rs +++ b/tfcli/src/host.rs @@ -1,14 +1,17 @@ use crate::api::APIErrorResponse; -use crate::{HostCommands, HostOverrideCommands}; +use crate::{HostCommands, HostOverrideCommands, TableStyle}; use serde::{Deserialize, Serialize}; use std::error::Error; use std::fs; use std::net::{Ipv4Addr, SocketAddrV4}; +use comfy_table::modifiers::UTF8_ROUND_CORNERS; +use comfy_table::presets::UTF8_FULL; +use comfy_table::Table; use url::Url; pub async fn host_main(command: HostCommands, server: Url) -> Result<(), Box> { match command { - HostCommands::List {} => list_hosts(server).await, + HostCommands::List { table_style } => list_hosts(server, table_style).await, HostCommands::Create { name, network_id, @@ -100,7 +103,7 @@ pub struct Host { pub metadata: HostMetadata, } -pub async fn list_hosts(server: Url) -> Result<(), Box> { +pub async fn list_hosts(server: Url, table_style: TableStyle) -> Result<(), Box> { let client = reqwest::Client::new(); // load session token @@ -120,46 +123,67 @@ pub async fn list_hosts(server: Url) -> Result<(), Box> { if res.status().is_success() { let resp: HostListResp = res.json().await?; - for host in &resp.data { - println!(" Host: {} ({})", host.name, host.id); - println!(" Organization: {}", host.organization_id); - println!(" Network: {}", host.network_id); - println!(" Role: {}", host.role_id); - println!(" IP Address: {}", host.ip_address); - println!( - " Static Addresses: {}", - host.static_addresses - .iter() - .map(|u| u.to_string()) - .collect::>() - .join(", ") - ); - println!(" Listen Port: {}", host.listen_port); - println!( - " Type: {}", - if host.is_lighthouse { - "Lighthouse" - } else if host.is_relay { - "Relay" - } else { - "Host" - } - ); - println!(" Blocked: {}", host.is_blocked); - println!(" Last Seen: {}", host.metadata.last_seen_at); - println!(" Client Version: {}", host.metadata.version); - println!(" Platform: {}", host.metadata.platform); - println!( - "Client Update Available: {}", - host.metadata.update_available - ); - println!(" Created: {}", host.created_at); - println!(); - } - if resp.data.is_empty() { println!("No hosts found"); + return Ok(()); } + + if matches!(table_style, TableStyle::List) { + for host in &resp.data { + println!(" Host: {} ({})", host.name, host.id); + println!(" Organization: {}", host.organization_id); + println!(" Network: {}", host.network_id); + println!(" Role: {}", host.role_id); + println!(" IP Address: {}", host.ip_address); + println!( + " Static Addresses: {}", + host.static_addresses + .iter() + .map(|u| u.to_string()) + .collect::>() + .join(", ") + ); + println!(" Listen Port: {}", host.listen_port); + println!( + " Type: {}", + if host.is_lighthouse { + "Lighthouse" + } else if host.is_relay { + "Relay" + } else { + "Host" + } + ); + println!(" Blocked: {}", host.is_blocked); + println!(" Last Seen: {}", host.metadata.last_seen_at); + println!(" Client Version: {}", host.metadata.version); + println!(" Platform: {}", host.metadata.platform); + println!( + "Client Update Available: {}", + host.metadata.update_available + ); + println!(" Created: {}", host.created_at); + println!(); + } + return Ok(()); + } + + let mut table = Table::new(); + match table_style { + TableStyle::List => unreachable!(), + TableStyle::Basic => (), + TableStyle::Pretty => { table.load_preset(UTF8_FULL).apply_modifier(UTF8_ROUND_CORNERS) ; }, + }; + + table.set_header(vec!["ID", "Name", "Organization ID", "Network ID", "Role ID", "IP Address", "Static Addresses", "Listen Port", "Type", "Blocked", "Last Seen"]); + + for host in &resp.data { + table.add_row(vec![host.id.as_str(), &host.name, &host.organization_id, &host.network_id, &host.role_id, &host.ip_address, &host.static_addresses.iter().map(|u| u.to_string()).collect::>().join(" "), &host.listen_port.to_string(), if host.is_lighthouse { "Lighthouse" } else if host.is_relay { "Relay" } else { "Host" }, if host.is_blocked { "true" } else { "false" }, &host.metadata.last_seen_at]); + } + + println!("{table}"); + + } else { let resp: APIErrorResponse = res.json().await?; diff --git a/tfcli/src/main.rs b/tfcli/src/main.rs index 64009e5..673d2d4 100644 --- a/tfcli/src/main.rs +++ b/tfcli/src/main.rs @@ -175,7 +175,10 @@ pub enum HostCommands { static_address: Option, }, /// List all hosts on your network - List {}, + List { + #[clap(short = 'T', long, default_value_t = TableStyle::Basic)] + table_style: TableStyle + }, /// Lookup a specific host by it's ID Lookup { #[clap(short, long)]