Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(rust): tuify tcp-inlet delete command #6886

Merged
merged 1 commit into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,9 @@ impl BackgroundNode {
let route = self.create_route().await?;
Ok(Client::new(&route, timeout))
}

/// Get the node name
pub fn name(&self) -> &str {
&self.node_name
}
}
42 changes: 24 additions & 18 deletions implementations/rust/ockam/ockam_command/src/node/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,24 @@ async fn run_impl(
_ctx: Context,
(opts, cmd): (CommandGlobalOpts, DeleteCommand),
) -> miette::Result<()> {
NodeDeleteTui::run(opts, cmd).await
DeleteTui::run(opts, cmd).await
}

pub struct NodeDeleteTui {
pub struct DeleteTui {
opts: CommandGlobalOpts,
cmd: DeleteCommand,
}

impl NodeDeleteTui {
impl DeleteTui {
pub async fn run(opts: CommandGlobalOpts, cmd: DeleteCommand) -> miette::Result<()> {
let tui = Self { opts, cmd };
tui.delete().await
}
}

#[ockam_core::async_trait]
impl DeleteCommandTui for NodeDeleteTui {
const ITEM_NAME: &'static str = "nodes";
impl DeleteCommandTui for DeleteTui {
const ITEM_NAME: &'static str = "node";

fn cmd_arg_item_name(&self) -> Option<&str> {
self.cmd.node_name.as_deref()
Expand All @@ -81,39 +81,45 @@ impl DeleteCommandTui for NodeDeleteTui {
self.opts.terminal.clone()
}

fn list_items_names(&self) -> miette::Result<Vec<String>> {
async fn get_arg_item_name_or_default(&self) -> miette::Result<String> {
Ok(get_node_name(&self.opts.state, &self.cmd.node_name))
}

async fn list_items_names(&self) -> miette::Result<Vec<String>> {
Ok(self.opts.state.nodes.list_items_names()?)
}

async fn delete_single(&self) -> miette::Result<()> {
let node_name = get_node_name(&self.opts.state, &self.cmd.node_name);
async fn delete_single(&self, item_name: &str) -> miette::Result<()> {
self.opts
.state
.nodes
.delete_sigkill(&node_name, self.cmd.force)?;
.delete_sigkill(item_name, self.cmd.force)?;
self.terminal()
.stdout()
.plain(fmt_ok!("Node with name '{node_name}' has been deleted"))
.machine(&node_name)
.json(serde_json::json!({ "name": &node_name }))
.plain(fmt_ok!(
"Node with name {} has been deleted",
item_name.light_magenta()
))
.machine(item_name)
.json(serde_json::json!({ "name": &item_name }))
.write_line()?;
Ok(())
}

async fn delete_multiple(&self, selected_items_names: Vec<String>) -> miette::Result<()> {
let plain = selected_items_names
.iter()
async fn delete_multiple(&self, items_names: Vec<String>) -> miette::Result<()> {
let plain = items_names
.into_iter()
.map(|name| {
if self
.opts
.state
.nodes
.delete_sigkill(name, self.cmd.force)
.delete_sigkill(&name, self.cmd.force)
.is_ok()
{
fmt_ok!("Node '{name}' deleted\n")
fmt_ok!("Node {} deleted\n", name.light_magenta())
} else {
fmt_warn!("Failed to delete node '{name}'\n")
fmt_warn!("Failed to delete node {}\n", name.light_magenta())
}
})
.collect::<String>();
Expand Down
19 changes: 11 additions & 8 deletions implementations/rust/ockam/ockam_command/src/node/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ async fn run_impl(
ctx: Context,
(opts, cmd): (CommandGlobalOpts, ShowCommand),
) -> miette::Result<()> {
NodeShowTui::run(ctx, opts, cmd.node_name).await
ShowTui::run(ctx, opts, cmd.node_name).await
}

pub struct NodeShowTui {
pub struct ShowTui {
ctx: Context,
opts: CommandGlobalOpts,
node_name: Option<String>,
}

impl NodeShowTui {
impl ShowTui {
pub async fn run(
ctx: Context,
opts: CommandGlobalOpts,
Expand All @@ -78,7 +78,7 @@ impl NodeShowTui {
}

#[ockam_core::async_trait]
impl ShowCommandTui for NodeShowTui {
impl ShowCommandTui for ShowTui {
const ITEM_NAME: &'static str = "nodes";

fn cmd_arg_item_name(&self) -> Option<&str> {
Expand All @@ -89,14 +89,17 @@ impl ShowCommandTui for NodeShowTui {
self.opts.terminal.clone()
}

async fn get_arg_item_name_or_default(&self) -> miette::Result<String> {
Ok(get_node_name(&self.opts.state, &self.node_name))
}

async fn list_items_names(&self) -> miette::Result<Vec<String>> {
Ok(self.opts.state.nodes.list_items_names()?)
}

async fn show_single(&self) -> miette::Result<()> {
let node_name = get_node_name(&self.opts.state, &self.node_name);
let mut node = BackgroundNode::create(&self.ctx, &self.opts.state, &node_name).await?;
print_query_status(&self.opts, &self.ctx, &node_name, &mut node, false).await?;
async fn show_single(&self, item_name: &str) -> miette::Result<()> {
let mut node = BackgroundNode::create(&self.ctx, &self.opts.state, item_name).await?;
print_query_status(&self.opts, &self.ctx, item_name, &mut node, false).await?;
Ok(())
}

Expand Down
130 changes: 103 additions & 27 deletions implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
use clap::Args;
use colorful::Colorful;
use miette::{miette, IntoDiagnostic};
use console::Term;
use miette::miette;

use ockam::Context;
use ockam_api::nodes::models::portal::InletList;
use ockam_api::nodes::service::portals::Inlets;
use ockam_api::nodes::BackgroundNode;
use ockam_core::api::Request;

use crate::fmt_ok;
use crate::node::{get_node_name, initialize_node_if_default, NodeOpts};
use crate::tcp::util::alias_parser;
use crate::terminal::tui::DeleteCommandTui;
use crate::util::{node_rpc, parse_node_name};
use crate::{docs, CommandGlobalOpts};
use crate::{docs, fmt_warn, CommandGlobalOpts, Terminal, TerminalStream};

const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt");

Expand All @@ -19,8 +23,8 @@ const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"
#[command(after_long_help = docs::after_help(AFTER_LONG_HELP))]
pub struct DeleteCommand {
/// Delete the inlet with this alias
#[arg(display_order = 900, required = true, id = "ALIAS", value_parser = alias_parser)]
alias: String,
#[arg(display_order = 900, id = "ALIAS", value_parser = alias_parser)]
alias: Option<String>,

/// Node on which to stop the tcp inlet. If none are provided, the default node will be used
#[command(flatten)]
Expand All @@ -42,31 +46,103 @@ pub async fn run_impl(
ctx: Context,
(opts, cmd): (CommandGlobalOpts, DeleteCommand),
) -> miette::Result<()> {
let node_name = get_node_name(&opts.state, &cmd.node_opts.at_node);
let node_name = parse_node_name(&node_name)?;
let node = BackgroundNode::create(&ctx, &opts.state, &node_name).await?;
if opts
.terminal
.confirmed_with_flag_or_prompt(cmd.yes, "Are you sure you want to delete this TCP inlet?")?
{
let alias = cmd.alias;
node.delete_inlet(&ctx, &alias)
.await?
.found()
.into_diagnostic()?
.ok_or(miette!(
"TCP inlet with alias {alias} was not found on Node {node_name}"
))?;

opts.terminal
DeleteTui::run(ctx, opts, cmd).await
}

struct DeleteTui {
ctx: Context,
opts: CommandGlobalOpts,
node: BackgroundNode,
cmd: DeleteCommand,
}

impl DeleteTui {
pub async fn run(
ctx: Context,
opts: CommandGlobalOpts,
cmd: DeleteCommand,
) -> miette::Result<()> {
let node_name = {
let name = get_node_name(&opts.state, &cmd.node_opts.at_node);
parse_node_name(&name)?
};
let node = BackgroundNode::create(&ctx, &opts.state, &node_name).await?;
let tui = Self {
ctx,
opts,
node,
cmd,
};
tui.delete().await
}
}

#[ockam_core::async_trait]
impl DeleteCommandTui for DeleteTui {
const ITEM_NAME: &'static str = "inlet";

fn cmd_arg_item_name(&self) -> Option<&str> {
self.cmd.alias.as_deref()
}

fn cmd_arg_delete_all(&self) -> bool {
false
}

fn cmd_arg_confirm_deletion(&self) -> bool {
self.cmd.yes
}

fn terminal(&self) -> Terminal<TerminalStream<Term>> {
self.opts.terminal.clone()
}

async fn get_arg_item_name_or_default(&self) -> miette::Result<String> {
self.cmd.alias.clone().ok_or(miette!("No alias provided"))
}

async fn list_items_names(&self) -> miette::Result<Vec<String>> {
let inlets: InletList = self
.node
.ask(&self.ctx, Request::get("/node/inlet"))
.await?;
let names = inlets.list.into_iter().map(|i| i.alias).collect();
Ok(names)
}

async fn delete_single(&self, item_name: &str) -> miette::Result<()> {
let node_name = self.node.name();
self.node.delete_inlet(&self.ctx, item_name).await?;
self.terminal()
.stdout()
.plain(fmt_ok!(
"TCP inlet with alias {alias} on Node {node_name} has been deleted"
"TCP inlet with alias {} on Node {} has been deleted",
item_name.light_magenta(),
node_name.light_magenta()
))
.machine(&alias)
.json(serde_json::json!({ "alias": alias, "node": node_name }))
.write_line()
.unwrap();
.write_line()?;
Ok(())
}

async fn delete_multiple(&self, items_names: Vec<String>) -> miette::Result<()> {
let node_name = self.node.name();
let mut plain = String::new();
for item_name in items_names {
if self.node.delete_inlet(&self.ctx, &item_name).await.is_ok() {
plain.push_str(&fmt_ok!(
"TCP inlet with alias {} on Node {} has been deleted\n",
item_name.light_magenta(),
node_name.light_magenta()
));
} else {
plain.push_str(&fmt_warn!(
"Failed to delete TCP inlet with alias {} on Node {}\n",
item_name.light_magenta(),
node_name.light_magenta()
));
}
}
self.terminal().stdout().plain(plain).write_line()?;
Ok(())
}
Ok(())
}
Loading
Loading