From 219121a5a5b918694f13f3c3a505a1d067d2476f Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Mon, 26 Aug 2024 12:46:52 -0700 Subject: [PATCH] `omdb nexus blueprints target set --diff` (#6435) --- dev-tools/omdb/src/bin/omdb/nexus.rs | 48 ++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/dev-tools/omdb/src/bin/omdb/nexus.rs b/dev-tools/omdb/src/bin/omdb/nexus.rs index ede2743404..db9e2cba52 100644 --- a/dev-tools/omdb/src/bin/omdb/nexus.rs +++ b/dev-tools/omdb/src/bin/omdb/nexus.rs @@ -51,6 +51,7 @@ use std::collections::BTreeMap; use std::collections::BTreeSet; use std::str::FromStr; use tabled::Tabled; +use tokio::sync::OnceCell; use uuid::Uuid; /// Arguments to the "omdb nexus" subcommand @@ -244,6 +245,10 @@ struct BlueprintTargetSetArgs { blueprint_id: Uuid, /// whether this blueprint should be enabled enabled: BlueprintTargetSetEnabled, + /// if specified, diff against the current target and wait for confirmation + /// before proceeding + #[clap(long)] + diff: bool, } #[derive(Debug, Clone, Copy, ValueEnum)] @@ -1722,6 +1727,38 @@ async fn cmd_nexus_blueprints_target_set( args: &BlueprintTargetSetArgs, _destruction_token: DestructiveOperationToken, ) -> Result<(), anyhow::Error> { + // Helper to only fetch the current target once. We may need it immediately + // if `args.diff` is true, or later if `args.enabled` is "inherit" (or + // both). + let current_target = OnceCell::new(); + let get_current_target = || async { + current_target + .get_or_try_init(|| client.blueprint_target_view()) + .await + .context("failed to fetch current target blueprint") + }; + + if args.diff { + let current_target = get_current_target().await?; + let blueprint1 = client + .blueprint_view(¤t_target.target_id) + .await + .context("failed to fetch target blueprint")? + .into_inner(); + let blueprint2 = + client.blueprint_view(&args.blueprint_id).await.with_context( + || format!("fetching blueprint {}", args.blueprint_id), + )?; + let diff = blueprint2.diff_since_blueprint(&blueprint1); + println!("{}", diff.display()); + println!( + "\nDo you want to make {} the target blueprint?", + args.blueprint_id + ); + let mut prompt = ConfirmationPrompt::new(); + prompt.read_and_validate("y/N", "y")?; + } + let enabled = match args.enabled { BlueprintTargetSetEnabled::Enabled => true, BlueprintTargetSetEnabled::Disabled => false, @@ -1734,12 +1771,11 @@ async fn cmd_nexus_blueprints_target_set( // operator. (In the case of the current target blueprint being changed // entirely, that will result in a failure to set the current target // below, because its parent will no longer be the current target.) - BlueprintTargetSetEnabled::Inherit => client - .blueprint_target_view() - .await - .map(|current| current.into_inner().enabled) - .context("failed to fetch current target blueprint")?, + BlueprintTargetSetEnabled::Inherit => { + get_current_target().await?.enabled + } }; + client .blueprint_target_set(&nexus_client::types::BlueprintTargetSet { target_id: args.blueprint_id, @@ -1966,7 +2002,7 @@ impl ConfirmationPrompt { { Ok(input) } else { - bail!("expungement aborted") + bail!("operation aborted") } }