diff --git a/rs/cli/src/cli.rs b/rs/cli/src/cli.rs index 46939599..9dd20768 100644 --- a/rs/cli/src/cli.rs +++ b/rs/cli/src/cli.rs @@ -253,6 +253,10 @@ pub(crate) mod nodes { /// Specifies the filter used to remove extra nodes extra_nodes_filter: Vec, + /// Features or Node IDs to not remove (exclude from the removal) + #[clap(long, num_args(1..))] + exclude: Vec, + /// Motivation for removing additional nodes #[clap(long)] motivation: Option, diff --git a/rs/cli/src/main.rs b/rs/cli/src/main.rs index 757d580f..bef203f4 100644 --- a/rs/cli/src/main.rs +++ b/rs/cli/src/main.rs @@ -206,7 +206,7 @@ async fn main() -> Result<(), anyhow::Error> { cli::Commands::Nodes(nodes) => { match &nodes.subcommand { - cli::nodes::Commands::Remove { extra_nodes_filter, no_auto, motivation } => { + cli::nodes::Commands::Remove { extra_nodes_filter, no_auto, exclude, motivation } => { if motivation.is_none() && !extra_nodes_filter.is_empty() { cmd.error( ErrorKind::MissingRequiredArgument, @@ -218,6 +218,7 @@ async fn main() -> Result<(), anyhow::Error> { runner.remove_nodes(NodesRemoveRequest { extra_nodes_filter: extra_nodes_filter.clone(), no_auto: *no_auto, + exclude: Some(exclude.clone()), motivation: motivation.clone().unwrap_or_default(), }).await }, diff --git a/rs/ic-management-backend/src/endpoints/nodes.rs b/rs/ic-management-backend/src/endpoints/nodes.rs index 43326756..6c2ca39e 100644 --- a/rs/ic-management-backend/src/endpoints/nodes.rs +++ b/rs/ic-management-backend/src/endpoints/nodes.rs @@ -37,6 +37,15 @@ async fn remove( } let decentralization_node = DecentralizationNode::from(&n); + + if let Some(exclude) = request.exclude.as_ref() { + for exclude_feature in exclude { + if decentralization_node.matches_feature_value(exclude_feature) { + return None; + } + } + } + if let Some(filter) = request .extra_nodes_filter .iter() diff --git a/rs/ic-management-types/src/requests.rs b/rs/ic-management-types/src/requests.rs index 61128cc9..1289b666 100644 --- a/rs/ic-management-types/src/requests.rs +++ b/rs/ic-management-types/src/requests.rs @@ -48,6 +48,7 @@ pub struct SubnetResizeRequest { pub struct NodesRemoveRequest { pub no_auto: bool, pub extra_nodes_filter: Vec, + pub exclude: Option>, pub motivation: String, }