76 lines
2.0 KiB
Rust
76 lines
2.0 KiB
Rust
use chrono::prelude::*;
|
|
use structopt::StructOpt;
|
|
use tailscale_api::*;
|
|
|
|
#[derive(StructOpt, Debug)]
|
|
struct Opt {
|
|
/// The domain associated with your tailscale account.
|
|
#[structopt(env = "TAILSCALE_DOMAIN", long)]
|
|
domain: String,
|
|
|
|
/// The tailscale API key as fetched from the admin panel.
|
|
#[structopt(env = "TAILSCALE_API_KEY", long, hide_env_values = true)]
|
|
api_key: String,
|
|
|
|
#[structopt(subcommand)]
|
|
command: Command,
|
|
}
|
|
|
|
#[derive(StructOpt, Debug)]
|
|
enum Command {
|
|
/// Prints or modifies the list of domains that Magic DNS uses.
|
|
Nameservers { servers: Vec<String> },
|
|
/// Prints or modifies the list of DNS search paths that Magic DNS uses.
|
|
Searchpaths { domains: Vec<String> },
|
|
/// Prints the list of devices in your tailscale network.
|
|
Devices,
|
|
}
|
|
|
|
fn main() -> Result {
|
|
let opt = Opt::from_args();
|
|
//println!("{:?}", opt);
|
|
|
|
let cli = Client::new(opt.domain, opt.api_key, "Xe/ts".to_string());
|
|
|
|
use Command::*;
|
|
match opt.command {
|
|
Nameservers { servers } => match servers.len() {
|
|
0 => println!("{:?}", cli.get_nameservers()?),
|
|
_ => println!("{:?}", cli.set_nameservers(servers)?),
|
|
},
|
|
Searchpaths { domains } => match domains.len() {
|
|
0 => println!("{:?}", cli.get_search_paths()?),
|
|
_ => println!("{:?}", cli.set_search_paths(domains)?),
|
|
},
|
|
Devices => {
|
|
let _ = cli
|
|
.devices()?
|
|
.devices
|
|
.into_iter()
|
|
.map(device_row)
|
|
.for_each(|dev| println!("{}", dev));
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn device_row(d: Device) -> String {
|
|
format!(
|
|
"{}, {}, {}, {}, {}",
|
|
d.display_node_key,
|
|
d.hostname,
|
|
d.os,
|
|
d.client_version,
|
|
{
|
|
let delta = Utc::now() - d.last_seen;
|
|
format!(
|
|
"last seen {} days {} hours {} minutes ago",
|
|
delta.num_days(),
|
|
delta.num_hours() % 24,
|
|
delta.num_minutes() % 60
|
|
)
|
|
}
|
|
)
|
|
}
|