use std::error::Error; use std::fs; use serde::Deserialize; use url::Url; use crate::api::APIErrorResponse; use crate::NetworkCommands; pub async fn network_main(command: NetworkCommands, server: Url) -> Result<(), Box> { match command { NetworkCommands::List {} => list_networks(server).await, NetworkCommands::Lookup {id} => get_network(id, server).await } } #[derive(Deserialize)] pub struct NetworkListResp { pub data: Vec } #[derive(Deserialize)] pub struct Network { pub id: String, pub cidr: String, #[serde(rename = "organizationID")] pub organization_id: String, #[serde(rename = "signingCAID")] pub signing_ca_id: String, #[serde(rename = "createdAt")] pub created_at: String, #[serde(rename = "lighthousesAsRelays")] pub lighthouses_as_relays: bool, pub name: String } pub async fn list_networks(server: Url) -> Result<(), Box> { let client = reqwest::Client::new(); // load session token let sess_token_store = dirs::config_dir().unwrap().join("tfcli-session.token"); let session_token = fs::read_to_string(&sess_token_store)?; let auth_token_store = dirs::config_dir().unwrap().join("tfcli-auth.token"); let auth_token = fs::read_to_string(&auth_token_store)?; let token = format!("{} {}", session_token, auth_token); let res = client.get(server.join("/v1/networks")?).bearer_auth(token).send().await?; if res.status().is_success() { let resp: NetworkListResp = res.json().await?; for network in &resp.data { println!(" Network: {}", network.id); println!(" CIDR: {}", network.cidr); println!(" Organization: {}", network.organization_id); println!(" Signing CA: {}", network.signing_ca_id); println!("Dedicated Relays: {}", !network.lighthouses_as_relays); println!(" Name: {}", network.name); println!(" Created At: {}", network.created_at); println!(); } if resp.data.is_empty() { println!("No networks found"); } } else { let resp: APIErrorResponse = res.json().await?; eprintln!("[error] Error listing networks: {} {}", resp.errors[0].code, resp.errors[0].message); std::process::exit(1); } Ok(()) } #[derive(Deserialize)] pub struct NetworkGetResponse { pub data: Network } pub async fn get_network(id: String, server: Url) -> Result<(), Box> { let client = reqwest::Client::new(); // load session token let sess_token_store = dirs::config_dir().unwrap().join("tfcli-session.token"); let session_token = fs::read_to_string(&sess_token_store)?; let auth_token_store = dirs::config_dir().unwrap().join("tfcli-auth.token"); let auth_token = fs::read_to_string(&auth_token_store)?; let token = format!("{} {}", session_token, auth_token); let res = client.get(server.join(&format!("/v1/networks/{}", id))?).bearer_auth(token).send().await?; if res.status().is_success() { let network: Network = res.json::().await?.data; println!(" Network: {}", network.id); println!(" CIDR: {}", network.cidr); println!(" Organization: {}", network.organization_id); println!(" Signing CA: {}", network.signing_ca_id); println!("Dedicated Relays: {}", !network.lighthouses_as_relays); println!(" Name: {}", network.name); println!(" Created At: {}", network.created_at); } else { let resp: APIErrorResponse = res.json().await?; eprintln!("[error] Error listing networks: {} {}", resp.errors[0].code, resp.errors[0].message); std::process::exit(1); } Ok(()) }