From 50c802745c214181649ec9bc0de7dd439a419398 Mon Sep 17 00:00:00 2001 From: Ben Blier Date: Mon, 18 May 2026 09:27:25 -0400 Subject: [PATCH] cli: add doublezero geolocation probe subcommands --- CHANGELOG.md | 1 + client/doublezero/src/cli/command.rs | 9 ++++-- client/doublezero/src/cli/geolocation/mod.rs | 17 ++++++++++ .../doublezero/src/cli/geolocation/probe.rs | 30 ++++++++++++++++++ client/doublezero/src/cli/mod.rs | 1 + client/doublezero/src/main.rs | 31 +++++++++++++++++-- 6 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 client/doublezero/src/cli/geolocation/mod.rs create mode 100644 client/doublezero/src/cli/geolocation/probe.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index fec5f8d154..9b2286c1a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ## Unreleased - cli: `config set` accepts `--geo-program-id`; `config get` and `config set` print Geolocation Program ID +- cli: `doublezero geolocation probe ...` mirrors `doublezero-geolocation probe ...`; new `--geo-program-id` global flag ## [v0.23.0](https://github.com/malbeclabs/doublezero/compare/client/v0.22.0...client/v0.23.0) - 2026-05-15 diff --git a/client/doublezero/src/cli/command.rs b/client/doublezero/src/cli/command.rs index 8f80374581..9926de7bec 100644 --- a/client/doublezero/src/cli/command.rs +++ b/client/doublezero/src/cli/command.rs @@ -3,9 +3,9 @@ use crate::{ cli::{ accesspass::AccessPassCliCommand, config::ConfigCliCommand, contributor::ContributorCliCommand, device::DeviceCliCommand, exchange::ExchangeCliCommand, - globalconfig::GlobalConfigCliCommand, link::LinkCliCommand, location::LocationCliCommand, - permission::PermissionCliCommand, resource::ResourceCliCommand, tenant::TenantCliCommand, - user::UserCliCommand, + geolocation::GeolocationCliCommand, globalconfig::GlobalConfigCliCommand, + link::LinkCliCommand, location::LocationCliCommand, permission::PermissionCliCommand, + resource::ResourceCliCommand, tenant::TenantCliCommand, user::UserCliCommand, }, command::{ connect::ProvisioningCliCommand, disable::DisableCliCommand, @@ -97,6 +97,9 @@ pub enum Command { /// Manage multicast #[command()] Multicast(MulticastCliCommand), + /// Manage geolocation probes and users + #[command()] + Geolocation(GeolocationCliCommand), /// Export all data to files #[command()] Export(ExportCliCommand), diff --git a/client/doublezero/src/cli/geolocation/mod.rs b/client/doublezero/src/cli/geolocation/mod.rs new file mode 100644 index 0000000000..0e73d44316 --- /dev/null +++ b/client/doublezero/src/cli/geolocation/mod.rs @@ -0,0 +1,17 @@ +use clap::{Args, Subcommand}; + +pub mod probe; + +use probe::ProbeCliCommand; + +#[derive(Args, Debug)] +pub struct GeolocationCliCommand { + #[command(subcommand)] + pub command: GeolocationCommands, +} + +#[derive(Subcommand, Debug)] +pub enum GeolocationCommands { + /// Manage geolocation probes + Probe(ProbeCliCommand), +} diff --git a/client/doublezero/src/cli/geolocation/probe.rs b/client/doublezero/src/cli/geolocation/probe.rs new file mode 100644 index 0000000000..f94c51f47e --- /dev/null +++ b/client/doublezero/src/cli/geolocation/probe.rs @@ -0,0 +1,30 @@ +use clap::{Args, Subcommand}; +use doublezero_cli::geolocation::probe::{ + add_parent::AddParentGeoProbeCliCommand, create::CreateGeoProbeCliCommand, + delete::DeleteGeoProbeCliCommand, get::GetGeoProbeCliCommand, list::ListGeoProbeCliCommand, + remove_parent::RemoveParentGeoProbeCliCommand, update::UpdateGeoProbeCliCommand, +}; + +#[derive(Args, Debug)] +pub struct ProbeCliCommand { + #[command(subcommand)] + pub command: ProbeCommands, +} + +#[derive(Subcommand, Debug)] +pub enum ProbeCommands { + /// Create a new geolocation probe + Create(CreateGeoProbeCliCommand), + /// Update an existing probe + Update(UpdateGeoProbeCliCommand), + /// Delete a probe + Delete(DeleteGeoProbeCliCommand), + /// Get details of a specific probe + Get(GetGeoProbeCliCommand), + /// List all probes + List(ListGeoProbeCliCommand), + /// Add a parent device to a probe + AddParent(AddParentGeoProbeCliCommand), + /// Remove a parent device from a probe + RemoveParent(RemoveParentGeoProbeCliCommand), +} diff --git a/client/doublezero/src/cli/mod.rs b/client/doublezero/src/cli/mod.rs index a84db116ac..4661143e46 100644 --- a/client/doublezero/src/cli/mod.rs +++ b/client/doublezero/src/cli/mod.rs @@ -4,6 +4,7 @@ pub mod config; pub mod contributor; pub mod device; pub mod exchange; +pub mod geolocation; pub mod globalconfig; pub mod link; pub mod location; diff --git a/client/doublezero/src/main.rs b/client/doublezero/src/main.rs index 06a3b22518..964cf0cd6f 100644 --- a/client/doublezero/src/main.rs +++ b/client/doublezero/src/main.rs @@ -13,6 +13,7 @@ use crate::cli::{ config::ConfigCommands, device::{DeviceCommands, InterfaceCommands}, exchange::ExchangeCommands, + geolocation::{probe::ProbeCommands, GeolocationCommands}, globalconfig::{ AirdropCommands, AuthorityCommands, FeatureFlagsCommands, FoundationAllowlistCommands, GlobalConfigCommands, QaAllowlistCommands, @@ -22,9 +23,11 @@ use crate::cli::{ user::UserCommands, }; use doublezero_cli::{ - checkversion::check_version, doublezerocommand::CliCommandImpl, version::VersionCliCommand, + checkversion::check_version, doublezerocommand::CliCommandImpl, + geoclicommand::GeoCliCommandImpl, version::VersionCliCommand, }; -use doublezero_sdk::{DZClient, ProgramVersion}; +use doublezero_sdk::{geolocation::client::GeoClient, DZClient, ProgramVersion}; +use doublezero_serviceability::pda::get_globalstate_pda; use servicecontroller::ServiceControllerImpl; #[derive(Parser, Debug)] @@ -47,6 +50,9 @@ struct App { /// DZ program ID (testnet or devnet) #[arg(long, value_name = "PROGRAM_ID", global = true)] program_id: Option, + /// Geolocation program ID + #[arg(long, value_name = "GEO_PROGRAM_ID", global = true)] + geo_program_id: Option, /// Path to the keypair file #[arg(long, value_name = "KEYPAIR", global = true)] keypair: Option, @@ -106,7 +112,7 @@ async fn main() -> eyre::Result<()> { (app.url, app.ws, app.program_id) }; - let dzclient = DZClient::new(url, ws, program_id, app.keypair)?; + let dzclient = DZClient::new(url.clone(), ws, program_id, app.keypair.clone())?; let client = CliCommandImpl::new(&dzclient); let stdout = std::io::stdout(); @@ -351,6 +357,25 @@ async fn main() -> eyre::Result<()> { cli::multicast::MulticastCommands::Unpublish(args) => args.execute(&client).await, }, + Command::Geolocation(command) => { + let geo_client = + GeoClient::new(url.clone(), app.geo_program_id.clone(), app.keypair.clone())?; + let svc_program_id = *dzclient.get_program_id(); + let (globalstate_pk, _) = get_globalstate_pda(&svc_program_id); + let geo_cli = GeoCliCommandImpl::new(&geo_client, &dzclient, globalstate_pk); + match command.command { + GeolocationCommands::Probe(command) => match command.command { + ProbeCommands::Create(args) => args.execute(&geo_cli, &mut handle), + ProbeCommands::Update(args) => args.execute(&geo_cli, &mut handle), + ProbeCommands::Delete(args) => args.execute(&geo_cli, &mut handle), + ProbeCommands::Get(args) => args.execute(&geo_cli, &mut handle), + ProbeCommands::List(args) => args.execute(&geo_cli, &mut handle), + ProbeCommands::AddParent(args) => args.execute(&geo_cli, &mut handle), + ProbeCommands::RemoveParent(args) => args.execute(&geo_cli, &mut handle), + }, + } + } + Command::Resource(command) => match command.command { cli::resource::ResourceCommands::Allocate(args) => args.execute(&client, &mut handle), cli::resource::ResourceCommands::Create(args) => args.execute(&client, &mut handle),