Skip to content

Commit

Permalink
refactor(plugin): expand scope of ExecuteOperations trait
Browse files Browse the repository at this point in the history
The Trait ExecuteOptions requires a specific type from the this repo to work.
This poses as a limitation for repos which use this codebase as a git module.
This change adheres to the patterns where a clap::Parser struct instance is
passed to the function, while removing dependency on the exact type of clap::Parser.
Also, adds an output argument to support the existing users of this trait
who depend on the CliArgs.output member from the cli_args arg.

Signed-off-by: Niladri Halder <[email protected]>
  • Loading branch information
niladrih committed Jan 3, 2025
1 parent 27ab9dc commit 589c51b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 61 deletions.
2 changes: 1 addition & 1 deletion control-plane/plugin/src/bin/rest-plugin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl CliArgs {
)
.context(RestClientSnafu)?;
self.operation
.execute(&self.args)
.execute(CliArgs::args().args, Some(&CliArgs::args().args.output))
.await
.context(ResourcesSnafu)
}
Expand Down
147 changes: 87 additions & 60 deletions control-plane/plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extern crate prettytable;
extern crate lazy_static;

use operations::{Label, SetProperty};
use resources::LabelResources;
use resources::{error::OutputFormatAbsentSnafu, utils::OutputFormat, LabelResources};
use std::fmt::Debug;
use utils::tracing_telemetry::{FmtLayer, FmtStyle};

Expand Down Expand Up @@ -43,14 +43,18 @@ impl Drop for TracingFlusher {
pub trait ExecuteOperation {
type Args;
type Error;
async fn execute(&self, cli_args: &Self::Args) -> Result<(), Self::Error>;
async fn execute(
&self,
cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> Result<(), Self::Error>;
}

#[derive(clap::Parser, Debug)]
#[derive(Clone, clap::Parser, Debug)]
pub struct CliArgs {
/// The Output, viz yaml, json.
#[clap(global = true, default_value = resources::utils::OutputFormat::None.as_ref(), short, long)]
pub output: resources::utils::OutputFormat,
#[clap(global = true, default_value = OutputFormat::None.as_ref(), short, long)]
pub output: OutputFormat,

/// Trace rest requests to the Jaeger endpoint agent.
#[clap(global = true, long, short)]
Expand Down Expand Up @@ -93,15 +97,19 @@ impl CliArgs {
impl ExecuteOperation for Operations {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
match self {
Operations::Drain(resource) => resource.execute(cli_args).await,
Operations::Get(resource) => resource.execute(cli_args).await,
Operations::Scale(resource) => resource.execute(cli_args).await,
Operations::Set(resource) => resource.execute(cli_args).await,
Operations::Cordon(resource) => resource.execute(cli_args).await,
Operations::Uncordon(resource) => resource.execute(cli_args).await,
Operations::Label(resource) => resource.execute(cli_args).await,
Operations::Drain(resource) => resource.execute(cli_args, output).await,
Operations::Get(resource) => resource.execute(cli_args, output).await,
Operations::Scale(resource) => resource.execute(cli_args, output).await,
Operations::Set(resource) => resource.execute(cli_args, output).await,
Operations::Cordon(resource) => resource.execute(cli_args, output).await,
Operations::Uncordon(resource) => resource.execute(cli_args, output).await,
Operations::Label(resource) => resource.execute(cli_args, output).await,
}
}
}
Expand All @@ -110,14 +118,19 @@ impl ExecuteOperation for Operations {
impl ExecuteOperation for DrainResources {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
_cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
let output = output.ok_or(OutputFormatAbsentSnafu.build())?;
match self {
DrainResources::Node(drain_node_args) => {
node::Node::drain(
&drain_node_args.node_id(),
drain_node_args.label(),
drain_node_args.drain_timeout(),
&cli_args.output,
output,
)
.await
}
Expand All @@ -129,62 +142,55 @@ impl ExecuteOperation for DrainResources {
impl ExecuteOperation for GetResources {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
_cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
let output = output.ok_or(OutputFormatAbsentSnafu.build())?;
match self {
GetResources::Cordon(get_cordon_resource) => match get_cordon_resource {
GetCordonArgs::Node { id: node_id } => {
cordon::NodeCordon::get(node_id, &cli_args.output).await
cordon::NodeCordon::get(node_id, output).await
}
GetCordonArgs::Nodes => cordon::NodeCordons::list(&cli_args.output).await,
GetCordonArgs::Nodes => cordon::NodeCordons::list(output).await,
},
GetResources::Drain(get_drain_resource) => match get_drain_resource {
GetDrainArgs::Node { id: node_id } => {
drain::NodeDrain::get(node_id, &cli_args.output).await
}
GetDrainArgs::Nodes => drain::NodeDrains::list(&cli_args.output).await,
GetDrainArgs::Node { id: node_id } => drain::NodeDrain::get(node_id, output).await,
GetDrainArgs::Nodes => drain::NodeDrains::list(output).await,
},
GetResources::Volumes(vol_args) => {
volume::Volumes::list(&cli_args.output, vol_args).await
}
GetResources::Volume { id } => volume::Volume::get(id, &cli_args.output).await,
GetResources::Volumes(vol_args) => volume::Volumes::list(output, vol_args).await,
GetResources::Volume { id } => volume::Volume::get(id, output).await,
GetResources::RebuildHistory { id } => {
volume::Volume::rebuild_history(id, &cli_args.output).await
volume::Volume::rebuild_history(id, output).await
}
GetResources::VolumeReplicaTopologies(vol_args) => {
volume::Volume::topologies(&cli_args.output, vol_args).await
volume::Volume::topologies(output, vol_args).await
}
GetResources::VolumeReplicaTopology { id } => {
volume::Volume::topology(id, &cli_args.output).await
}
GetResources::Pools(args) => pool::Pools::list(args, &cli_args.output).await,
GetResources::Pool(args) => {
pool::Pool::get(&args.pool_id(), args, &cli_args.output).await
}
GetResources::Nodes(args) => node::Nodes::list(args, &cli_args.output).await,
GetResources::Node(args) => {
node::Node::get(&args.node_id(), args, &cli_args.output).await
volume::Volume::topology(id, output).await
}
GetResources::Pools(args) => pool::Pools::list(args, output).await,
GetResources::Pool(args) => pool::Pool::get(&args.pool_id(), args, output).await,
GetResources::Nodes(args) => node::Nodes::list(args, output).await,
GetResources::Node(args) => node::Node::get(&args.node_id(), args, output).await,
GetResources::BlockDevices(bdargs) => {
blockdevice::BlockDevice::get_blockdevices(
&bdargs.node_id(),
&bdargs.all(),
&cli_args.output,
)
.await
blockdevice::BlockDevice::get_blockdevices(&bdargs.node_id(), &bdargs.all(), output)
.await
}
GetResources::VolumeSnapshots(snapargs) => {
snapshot::VolumeSnapshots::get_snapshots(
&snapargs.volume(),
&snapargs.snapshot(),
&cli_args.output,
output,
)
.await
}
GetResources::VolumeSnapshotTopology(snapargs) => {
snapshot::VolumeSnapshots::get_snapshot_topology(
&snapargs.volume(),
&snapargs.snapshot(),
&cli_args.output,
output,
)
.await
}
Expand All @@ -196,10 +202,15 @@ impl ExecuteOperation for GetResources {
impl ExecuteOperation for ScaleResources {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
_cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
let output = output.ok_or(OutputFormatAbsentSnafu.build())?;
match self {
ScaleResources::Volume { id, replica_count } => {
volume::Volume::scale(id, *replica_count, &cli_args.output).await
volume::Volume::scale(id, *replica_count, output).await
}
}
}
Expand All @@ -209,10 +220,15 @@ impl ExecuteOperation for ScaleResources {
impl ExecuteOperation for SetPropertyResources {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
_cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
let output = output.ok_or(OutputFormatAbsentSnafu.build())?;
match self {
SetPropertyResources::Volume { id, properties } => {
volume::Volume::set_property(id, properties, &cli_args.output).await
volume::Volume::set_property(id, properties, output).await
}
}
}
Expand All @@ -222,11 +238,14 @@ impl ExecuteOperation for SetPropertyResources {
impl ExecuteOperation for CordonResources {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
_cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
let output = output.ok_or(OutputFormatAbsentSnafu.build())?;
match self {
CordonResources::Node { id, label } => {
node::Node::cordon(id, label, &cli_args.output).await
}
CordonResources::Node { id, label } => node::Node::cordon(id, label, output).await,
}
}
}
Expand All @@ -235,11 +254,14 @@ impl ExecuteOperation for CordonResources {
impl ExecuteOperation for UnCordonResources {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
_cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
let output = output.ok_or(OutputFormatAbsentSnafu.build())?;
match self {
UnCordonResources::Node { id, label } => {
node::Node::uncordon(id, label, &cli_args.output).await
}
UnCordonResources::Node { id, label } => node::Node::uncordon(id, label, output).await,
}
}
}
Expand All @@ -248,18 +270,23 @@ impl ExecuteOperation for UnCordonResources {
impl ExecuteOperation for LabelResources {
type Args = CliArgs;
type Error = crate::resources::Error;
async fn execute(&self, cli_args: &CliArgs) -> PluginResult {
async fn execute(
&self,
_cli_args: impl clap::Parser,
output: Option<&OutputFormat>,
) -> PluginResult {
let output = output.ok_or(OutputFormatAbsentSnafu.build())?;
match self {
LabelResources::Node {
id,
label,
overwrite,
} => node::Node::label(id, label.to_string(), *overwrite, &cli_args.output).await,
} => node::Node::label(id, label.to_string(), *overwrite, output).await,
LabelResources::Pool {
id,
label,
overwrite,
} => pool::Pool::label(id, label.to_string(), *overwrite, &cli_args.output).await,
} => pool::Pool::label(id, label.to_string(), *overwrite, output).await,
}
}
}
3 changes: 3 additions & 0 deletions control-plane/plugin/src/resources/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ pub enum Error {
key1=value1,key2=value2"
))]
LabelNodeFilter { labels: String },

#[snafu(display("Expected output to be a Some"))]
OutputFormatAbsent,
}

/// Errors related to label topology formats.
Expand Down

0 comments on commit 589c51b

Please sign in to comment.