cleaning up
This commit is contained in:
1 parent
42cdc720a3
commit
826a41ae64
12 files changed
+98
-175
No files matched your search
+11
-20
@@ -24,8 +24,8 @@ pub struct Cli {
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Command {
|
||||
/// Show device status rows from neighbor/device data.
|
||||
Status(StatusArgs),
|
||||
/// Show merged device inventory rows.
|
||||
Inventory(InventoryArgs),
|
||||
/// Show DHCP leases, optionally enriched with current neighbor state.
|
||||
Leases(LeasesArgs),
|
||||
/// Send Wake-on-LAN packets from a query or explicit MAC/IP pair.
|
||||
@@ -70,12 +70,12 @@ pub struct WakeArgs {
|
||||
|
||||
#[derive(Args)]
|
||||
#[command(after_long_help = "Examples:
|
||||
wakey status bedroom-pc
|
||||
wakey status --mac aa:bb:cc:dd:ee:ff
|
||||
wakey status --dev br-lan --nud reachable
|
||||
wakey inventory bedroom-pc
|
||||
wakey inventory --mac aa:bb:cc:dd:ee:ff
|
||||
wakey inventory --dev br-lan --nud reachable
|
||||
|
||||
If only the positional query is provided, it is treated as free-form input and resolved through the smart selector path.")]
|
||||
pub struct StatusArgs {
|
||||
pub struct InventoryArgs {
|
||||
/// Free-form device query.
|
||||
pub query: Option<String>,
|
||||
/// Explicit name/text filter.
|
||||
@@ -138,21 +138,12 @@ pub async fn run(cli: Cli) -> Result<()> {
|
||||
init_tracing(cli.verbose);
|
||||
|
||||
match cli.command {
|
||||
Command::Status(args) => {
|
||||
Command::Inventory(args) => {
|
||||
let as_json = args.json;
|
||||
let query = status_args_to_query(args);
|
||||
let query = inventory_args_to_query(args);
|
||||
let selected_name = query.name.clone();
|
||||
debug!(?query, json = as_json, "dispatching status command");
|
||||
let status = if query.name.is_some()
|
||||
&& query.filter.ips.is_empty()
|
||||
&& query.filter.devs.is_empty()
|
||||
&& query.filter.nuds.is_empty()
|
||||
&& query.filter.macs.is_empty()
|
||||
{
|
||||
wakey::get_status_for_input(query.name.clone().unwrap_or_default()).await?
|
||||
} else {
|
||||
wakey::get_status(query).await?
|
||||
};
|
||||
debug!(?query, json = as_json, "dispatching inventory command");
|
||||
let status = wakey::inventory(query).await?;
|
||||
if as_json {
|
||||
println!("{}", serde_json::to_string_pretty(&status)?);
|
||||
} else {
|
||||
@@ -216,7 +207,7 @@ pub async fn run(cli: Cli) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn status_args_to_query(args: StatusArgs) -> DeviceQuery {
|
||||
fn inventory_args_to_query(args: InventoryArgs) -> DeviceQuery {
|
||||
if let Some(query) = args.query.as_ref()
|
||||
&& args.name.is_none()
|
||||
&& args.ips.is_empty()
|
||||
|
||||
+36
-25
@@ -5,31 +5,42 @@ use wakey_core::{DeviceInventory, DhcpLeaseWithState, InterfaceSummary, WakeResu
|
||||
pub fn render_status_table(status: &DeviceInventory) -> Table {
|
||||
let mut table = base_table();
|
||||
table.set_header(vec!["Name", "IP", "MAC", "Presence", "Interfaces"]);
|
||||
for row in &status.devices {
|
||||
table.add_row(vec![
|
||||
Cell::new(
|
||||
row.names
|
||||
.first()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| "(unnamed)".into()),
|
||||
),
|
||||
Cell::new(
|
||||
row.ips
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
),
|
||||
Cell::new(
|
||||
row.macs
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
),
|
||||
Cell::new(format!("{:?}", row.presence)),
|
||||
Cell::new(row.interfaces.join(", ")),
|
||||
]);
|
||||
for device in &status.devices {
|
||||
let name = device
|
||||
.names
|
||||
.first()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| "(unnamed)".into());
|
||||
let ips: Vec<String> = if device.ips.is_empty() {
|
||||
vec![String::new()]
|
||||
} else {
|
||||
device.ips.iter().map(ToString::to_string).collect()
|
||||
};
|
||||
let macs: Vec<String> = if device.macs.is_empty() {
|
||||
vec![String::new()]
|
||||
} else {
|
||||
device.macs.iter().map(ToString::to_string).collect()
|
||||
};
|
||||
let interfaces: Vec<String> = if device.interfaces.is_empty() {
|
||||
vec![String::new()]
|
||||
} else {
|
||||
device.interfaces.clone()
|
||||
};
|
||||
|
||||
let row_count = ips.len().max(macs.len()).max(interfaces.len());
|
||||
for idx in 0..row_count {
|
||||
table.add_row(vec![
|
||||
Cell::new(if idx == 0 { name.as_str() } else { "" }),
|
||||
Cell::new(ips.get(idx).cloned().unwrap_or_default()),
|
||||
Cell::new(macs.get(idx).cloned().unwrap_or_default()),
|
||||
Cell::new(if idx == 0 {
|
||||
format!("{:?}", device.presence)
|
||||
} else {
|
||||
String::new()
|
||||
}),
|
||||
Cell::new(interfaces.get(idx).cloned().unwrap_or_default()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
table
|
||||
}
|
||||
|
||||
+4
-4
@@ -2,10 +2,10 @@ pub mod service;
|
||||
pub mod utils;
|
||||
|
||||
pub use service::{
|
||||
StatusResponse, broadcast_wake_targets, get_interface_summaries, get_interface_summary,
|
||||
get_ips, get_leases, get_status, get_status_for_input, inventory, leases_without_state,
|
||||
list_interfaces, merge_devices, query_to_device_query, resolve_devices, resolve_query,
|
||||
resolve_selector, resolve_wake_targets, wake_explicit, wake_from_query, wake_targets,
|
||||
broadcast_wake_targets, get_interface_summaries, get_interface_summary, get_ips, get_leases,
|
||||
inventory, leases_without_state, list_interfaces, merge_devices, query_to_device_query,
|
||||
resolve_devices, resolve_query, resolve_selector, resolve_wake_targets, wake_explicit,
|
||||
wake_from_query, wake_targets,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -2,14 +2,12 @@ pub mod interfaces;
|
||||
pub mod inventory;
|
||||
pub mod leases;
|
||||
pub mod query;
|
||||
pub mod status;
|
||||
pub mod wake;
|
||||
|
||||
pub use interfaces::{get_interface_summaries, get_interface_summary, get_ips, list_interfaces};
|
||||
pub use inventory::{inventory, merge_devices, resolve_devices};
|
||||
pub use leases::{get_leases, leases_without_state};
|
||||
pub use query::{query_to_device_query, resolve_query, resolve_selector};
|
||||
pub use status::{StatusResponse, get_status, get_status_for_input};
|
||||
pub use wake::{
|
||||
broadcast_wake_targets, resolve_wake_targets, wake_explicit, wake_from_query, wake_targets,
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use tracing::{debug, instrument};
|
||||
use wakey_core::{DeviceInventory, DeviceQuery};
|
||||
|
||||
use crate::service::inventory::inventory;
|
||||
use crate::service::query::resolve_query;
|
||||
|
||||
/// Service status payload expressed in terms of merged device inventory.
|
||||
pub type StatusResponse = DeviceInventory;
|
||||
|
||||
/// Return status payload from merged device inventory.
|
||||
#[instrument(skip_all, fields(name = ?query.name))]
|
||||
pub async fn get_status(query: DeviceQuery) -> Result<StatusResponse> {
|
||||
let inventory = inventory(query).await?;
|
||||
debug!(devices = inventory.devices.len(), "built status response");
|
||||
Ok(inventory)
|
||||
}
|
||||
|
||||
/// Convenience wrapper around [`get_status`] for free-form user input.
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_status_for_input(input: impl Into<String>) -> Result<StatusResponse> {
|
||||
let query = resolve_query(input).await?;
|
||||
get_status(query).await
|
||||
}
|
||||
Reference in new issue
Block a user