Skip to content

Commit

Permalink
feat(wash-cli): add tag command to set and remove host labels
Browse files Browse the repository at this point in the history
Signed-off-by: Connor Smith <connor.smith.256@gmail.com>
  • Loading branch information
connorsmith256 committed Jan 3, 2024
1 parent 7fd1b09 commit b768883
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
6 changes: 6 additions & 0 deletions crates/wash-cli/src/bin/wash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use wash_lib::cli::scale::ScaleCommand;
use wash_lib::cli::spy::SpyCommand;
use wash_lib::cli::start::StartCommand;
use wash_lib::cli::stop::StopCommand;
use wash_lib::cli::tag::TagHostCommand;
use wash_lib::cli::update::UpdateCommand;
use wash_lib::cli::{CommandOutput, OutputKind};
use wash_lib::drain::Drain as DrainSelection;
Expand Down Expand Up @@ -70,6 +71,7 @@ Iterate:
link Link an actor and a provider
call Invoke a wasmCloud actor
ctl Interact with a wasmCloud control interface (deprecated, use above commands)
tag Tag (or un-tag) a host with a key=value label pair
Publish:
pull Pull an artifact from an OCI compliant registry
Expand Down Expand Up @@ -203,6 +205,9 @@ enum CliCommand {
/// Stop an actor, provider, or host
#[clap(name = "stop", subcommand)]
Stop(StopCommand),
/// Tag a host
#[clap(name = "tag")]
Tag(TagHostCommand),
/// Update an actor running in a host to a newer version
#[clap(name = "update", subcommand)]
Update(UpdateCommand),
Expand Down Expand Up @@ -282,6 +287,7 @@ async fn main() {
common::start_cmd::handle_command(start_cli, output_kind).await
}
CliCommand::Stop(stop_cli) => common::stop_cmd::handle_command(stop_cli, output_kind).await,
CliCommand::Tag(tag_cli) => common::tag_cmd::handle_command(tag_cli, output_kind).await,
CliCommand::Update(update_cli) => {
common::update_cmd::handle_command(update_cli, output_kind).await
}
Expand Down
1 change: 1 addition & 0 deletions crates/wash-cli/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pub mod registry_cmd;
pub mod scale_cmd;
pub mod start_cmd;
pub mod stop_cmd;
pub mod tag_cmd;
pub mod update_cmd;
16 changes: 16 additions & 0 deletions crates/wash-cli/src/common/tag_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use anyhow::Result;

use wash_lib::cli::{
tag::{handle_tag_host, TagHostCommand},
CommandOutput, OutputKind,
};

use crate::appearance::spinner::Spinner;

pub async fn handle_command(cmd: TagHostCommand, output_kind: OutputKind) -> Result<CommandOutput> {
let sp: Spinner = Spinner::new(&output_kind)?;
let out = handle_tag_host(cmd).await?;
sp.finish_and_clear();

Ok(out)
}
1 change: 1 addition & 0 deletions crates/wash-lib/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub mod scale;
pub mod spy;
pub mod start;
pub mod stop;
pub mod tag;
pub mod update;

/// Used for displaying human-readable output vs JSON format
Expand Down
79 changes: 79 additions & 0 deletions crates/wash-lib/src/cli/tag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use anyhow::{bail, Context, Result};
use clap::Parser;

use crate::{
common::{boxed_err_to_anyhow, find_host_id},
config::WashConnectionOptions,
};

use super::{CliConnectionOpts, CommandOutput};

#[derive(Debug, Clone, Parser)]
pub struct TagHostCommand {
#[clap(flatten)]
pub opts: CliConnectionOpts,

/// ID of host to update the actor on. If a non-ID is provided, the host will be selected based
/// on matching the prefix of the ID or the friendly name and will return an error if more than
/// one host matches.
#[clap(name = "host-id")]
pub host_id: String,

/// Delete the label, instead of adding it
#[clap(long = "delete", default_value = "false", conflicts_with("value"))]
pub delete: bool,

/// Host label key, e.g. "cloud"
#[clap(name = "key", alias = "label")]
pub key: String,

/// Host label value, e.g. "aws". Not required if `--delete` is set.
#[clap(name = "value", required_unless_present("delete"))]
pub value: Option<String>,
}

pub async fn handle_tag_host(cmd: TagHostCommand) -> Result<CommandOutput> {
let wco: WashConnectionOptions = cmd.opts.try_into()?;
let client = wco.into_ctl_client(None).await?;

let (host_id, friendly_name) = find_host_id(&cmd.host_id, &client).await?;

let friendly_name = if friendly_name.is_empty() {
host_id.to_string()
} else {
friendly_name
};

if cmd.delete {
let ack = client
.delete_label(&host_id, &cmd.key)
.await
.map_err(boxed_err_to_anyhow)?;
if !ack.accepted {
bail!("Operation failed: {}", ack.error);
}

Ok(CommandOutput::from_key_and_text(
"result",
format!("Host `{}` untagged with `{}`", friendly_name, cmd.key),
))
} else {
let value = cmd.value.context("No value provided")?;

let ack = client
.put_label(&host_id, &cmd.key, &value)
.await
.map_err(boxed_err_to_anyhow)?;
if !ack.accepted {
bail!("Operation failed: {}", ack.error);
}

Ok(CommandOutput::from_key_and_text(
"result",
format!(
"Host `{}` tagged with `{}={}`",
friendly_name, cmd.key, value
),
))
}
}

0 comments on commit b768883

Please sign in to comment.