cli: Add routing entries per rid and or nid
To allow third party tools read the routing table entries filtered by rid or nid and if needed in json format. Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
This commit is contained in:
parent
2d55ffba81
commit
76ba25268d
|
|
@ -3,6 +3,7 @@ use std::ffi::OsString;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
use radicle::node::{Address, Node, NodeId, ROUTING_DB_FILE, TRACKING_DB_FILE};
|
use radicle::node::{Address, Node, NodeId, ROUTING_DB_FILE, TRACKING_DB_FILE};
|
||||||
|
use radicle::prelude::Id;
|
||||||
|
|
||||||
use crate::terminal as term;
|
use crate::terminal as term;
|
||||||
use crate::terminal::args::{Args, Error, Help};
|
use crate::terminal::args::{Args, Error, Help};
|
||||||
|
|
@ -28,7 +29,7 @@ Usage
|
||||||
rad node start [--daemon|-d] [<option>...] [-- <node-option>...]
|
rad node start [--daemon|-d] [<option>...] [-- <node-option>...]
|
||||||
rad node stop [<option>...]
|
rad node stop [<option>...]
|
||||||
rad node connect <nid> <addr> [<option>...]
|
rad node connect <nid> <addr> [<option>...]
|
||||||
rad node routing [<option>...]
|
rad node routing [--rid <rid>] [--nid <nid>] [--json] [<option>...]
|
||||||
rad node tracking [--repos|--nodes] [<option>...]
|
rad node tracking [--repos|--nodes] [<option>...]
|
||||||
|
|
||||||
For `<node-option>` see `radicle-node --help`.
|
For `<node-option>` see `radicle-node --help`.
|
||||||
|
|
@ -38,6 +39,9 @@ Options
|
||||||
--help Print help
|
--help Print help
|
||||||
--repos Show the tracked repositories table
|
--repos Show the tracked repositories table
|
||||||
--nodes Show the tracked nodes table
|
--nodes Show the tracked nodes table
|
||||||
|
--rid Show the routing table entries for the given RID
|
||||||
|
--nid Show the routing table entries for the given NID
|
||||||
|
--json Output the routing table as json
|
||||||
"#,
|
"#,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -51,7 +55,11 @@ pub enum Operation {
|
||||||
addr: Address,
|
addr: Address,
|
||||||
},
|
},
|
||||||
Events,
|
Events,
|
||||||
Routing,
|
Routing {
|
||||||
|
json: bool,
|
||||||
|
rid: Option<Id>,
|
||||||
|
nid: Option<NodeId>,
|
||||||
|
},
|
||||||
Start {
|
Start {
|
||||||
daemon: bool,
|
daemon: bool,
|
||||||
options: Vec<OsString>,
|
options: Vec<OsString>,
|
||||||
|
|
@ -92,6 +100,8 @@ impl Args for Options {
|
||||||
let mut op: Option<OperationName> = None;
|
let mut op: Option<OperationName> = None;
|
||||||
let mut tracking_mode = TrackingMode::default();
|
let mut tracking_mode = TrackingMode::default();
|
||||||
let mut nid: Option<NodeId> = None;
|
let mut nid: Option<NodeId> = None;
|
||||||
|
let mut rid: Option<Id> = None;
|
||||||
|
let mut json: bool = false;
|
||||||
let mut addr: Option<Address> = None;
|
let mut addr: Option<Address> = None;
|
||||||
|
|
||||||
while let Some(arg) = parser.next()? {
|
while let Some(arg) = parser.next()? {
|
||||||
|
|
@ -123,6 +133,15 @@ impl Args for Options {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Long("rid") if matches!(op, Some(OperationName::Routing)) => {
|
||||||
|
let val = parser.value()?;
|
||||||
|
rid = term::args::rid(&val).ok();
|
||||||
|
}
|
||||||
|
Long("nid") if matches!(op, Some(OperationName::Routing)) => {
|
||||||
|
let val = parser.value()?;
|
||||||
|
nid = term::args::nid(&val).ok();
|
||||||
|
}
|
||||||
|
Long("json") if matches!(op, Some(OperationName::Routing)) => json = true,
|
||||||
Long("repos") if matches!(op, Some(OperationName::Tracking)) => {
|
Long("repos") if matches!(op, Some(OperationName::Tracking)) => {
|
||||||
tracking_mode = TrackingMode::Repos
|
tracking_mode = TrackingMode::Repos
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +164,7 @@ impl Args for Options {
|
||||||
addr: addr.ok_or_else(|| anyhow!("an address must be provided"))?,
|
addr: addr.ok_or_else(|| anyhow!("an address must be provided"))?,
|
||||||
},
|
},
|
||||||
OperationName::Events => Operation::Events,
|
OperationName::Events => Operation::Events,
|
||||||
OperationName::Routing => Operation::Routing,
|
OperationName::Routing => Operation::Routing { rid, nid, json },
|
||||||
OperationName::Start => Operation::Start { daemon, options },
|
OperationName::Start => Operation::Start { daemon, options },
|
||||||
OperationName::Status => Operation::Status,
|
OperationName::Status => Operation::Status,
|
||||||
OperationName::Stop => Operation::Stop,
|
OperationName::Stop => Operation::Stop,
|
||||||
|
|
@ -169,10 +188,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
let node = Node::new(profile.socket());
|
let node = Node::new(profile.socket());
|
||||||
events::run(node)?;
|
events::run(node)?;
|
||||||
}
|
}
|
||||||
Operation::Routing => {
|
Operation::Routing { rid, nid, json } => {
|
||||||
let store =
|
let store =
|
||||||
radicle::node::routing::Table::reader(profile.home.node().join(ROUTING_DB_FILE))?;
|
radicle::node::routing::Table::reader(profile.home.node().join(ROUTING_DB_FILE))?;
|
||||||
routing::run(&store)?;
|
routing::run(&store, rid, nid, json)?;
|
||||||
}
|
}
|
||||||
Operation::Start { daemon, options } => control::start(daemon, options)?,
|
Operation::Start { daemon, options } => control::start(daemon, options)?,
|
||||||
Operation::Status => {
|
Operation::Status => {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,31 @@
|
||||||
use radicle::node;
|
use radicle::node;
|
||||||
|
use radicle::prelude::{Id, NodeId};
|
||||||
|
|
||||||
use crate::terminal as term;
|
use crate::terminal as term;
|
||||||
use crate::terminal::Element;
|
use crate::terminal::Element;
|
||||||
|
|
||||||
pub fn run<S: node::routing::Store>(routing: &S) -> anyhow::Result<()> {
|
pub fn run<S: node::routing::Store>(
|
||||||
|
routing: &S,
|
||||||
|
rid: Option<Id>,
|
||||||
|
nid: Option<NodeId>,
|
||||||
|
json: bool,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
// Filters entries by RID or NID exclusively, or show all of them if none given.
|
||||||
|
let entries = routing.entries()?.filter(|(rid_, nid_)| {
|
||||||
|
(nid.is_none() || Some(nid_) == nid.as_ref())
|
||||||
|
&& (rid.is_none() || Some(rid_) == rid.as_ref())
|
||||||
|
});
|
||||||
|
|
||||||
|
if json {
|
||||||
|
print_json(entries);
|
||||||
|
} else {
|
||||||
|
print_table(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_table(entries: impl IntoIterator<Item = (Id, NodeId)>) {
|
||||||
let mut t = term::Table::new(term::table::TableOptions::bordered());
|
let mut t = term::Table::new(term::table::TableOptions::bordered());
|
||||||
t.push([
|
t.push([
|
||||||
term::format::default(String::from("RID")),
|
term::format::default(String::from("RID")),
|
||||||
|
|
@ -11,13 +33,17 @@ pub fn run<S: node::routing::Store>(routing: &S) -> anyhow::Result<()> {
|
||||||
]);
|
]);
|
||||||
t.divider();
|
t.divider();
|
||||||
|
|
||||||
for (id, node) in routing.entries()? {
|
for (rid, nid) in entries {
|
||||||
t.push([
|
t.push([
|
||||||
term::format::highlight(id.to_string()),
|
term::format::highlight(rid.to_string()),
|
||||||
term::format::default(term::format::node(&node)),
|
term::format::default(term::format::node(&nid)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
t.print();
|
t.print();
|
||||||
|
}
|
||||||
Ok(())
|
|
||||||
|
fn print_json(entries: impl IntoIterator<Item = (Id, NodeId)>) {
|
||||||
|
for (rid, nid) in entries {
|
||||||
|
println!("{}", serde_json::json!({ "rid": rid, "nid": nid }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue