Skip to content

Commit b4b2d8e

Browse files
New command: 'policies declare_blanket'
1 parent 8511087 commit b4b2d8e

File tree

6 files changed

+115
-9
lines changed

6 files changed

+115
-9
lines changed

Cargo.lock

Lines changed: 6 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1775,7 +1775,7 @@ fn operator_policies_subcommands(pre_flight_settings: PreFlightSettings) -> [Com
17751775
.map(|cmd| cmd.infer_long_args(pre_flight_settings.infer_long_options))
17761776
}
17771777

1778-
fn policies_subcommands(pre_flight_settings: PreFlightSettings) -> [Command; 11] {
1778+
fn policies_subcommands(pre_flight_settings: PreFlightSettings) -> [Command; 12] {
17791779
let declare_cmd = Command::new("declare")
17801780
.visible_aliases(vec!["update", "set"])
17811781
.about("Creates or updates a policy")
@@ -1834,6 +1834,30 @@ fn policies_subcommands(pre_flight_settings: PreFlightSettings) -> [Command; 11]
18341834
.help("additional definitions to merge into the new overriding policy"),
18351835
);
18361836

1837+
let declare_blanket_cmd = Command::new("declare_blanket")
1838+
.about("Creates a low priority blanket policy, a policy that matches all objects not matched by any other policy")
1839+
.after_help(color_print::cformat!("<bold>Doc guide:</bold>: {}", POLICY_GUIDE_URL))
1840+
.arg(
1841+
Arg::new("name")
1842+
.long("name")
1843+
.help("blanket policy name")
1844+
.required(true),
1845+
)
1846+
.arg(
1847+
Arg::new("apply_to")
1848+
.long("apply-to")
1849+
.alias("applies-to")
1850+
.help("entities to apply to (queues, classic_queues, quorum_queues, streams, exchanges, all)")
1851+
.value_parser(value_parser!(PolicyTarget))
1852+
.required(true),
1853+
)
1854+
.arg(
1855+
Arg::new("definition")
1856+
.long("definition")
1857+
.help("policy definition")
1858+
.required(true),
1859+
);
1860+
18371861
let list_cmd = Command::new("list")
18381862
.long_about("Lists policies")
18391863
.after_help(color_print::cformat!(
@@ -1948,6 +1972,7 @@ fn policies_subcommands(pre_flight_settings: PreFlightSettings) -> [Command; 11]
19481972
[
19491973
declare_cmd,
19501974
declare_override_cmd,
1975+
declare_blanket_cmd,
19511976
delete_cmd,
19521977
delete_definition_key_cmd,
19531978
delete_definition_key_from_all_in_cmd,

src/commands.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use std::fs;
3131
use std::io;
3232
use std::process;
3333

34+
use crate::constants::DEFAULT_BLANKET_POLICY_PRIORITY;
3435
use rabbitmq_http_client::commons::BindingDestinationType;
3536
use rabbitmq_http_client::commons::QueueType;
3637
use rabbitmq_http_client::responses::PolicyDefinitionOps;
@@ -1096,6 +1097,49 @@ pub fn declare_policy_override(
10961097
client.declare_policy(&params)
10971098
}
10981099

1100+
pub fn declare_blanket_policy(
1101+
client: APIClient,
1102+
vhost: &str,
1103+
command_args: &ArgMatches,
1104+
) -> ClientResult<()> {
1105+
// find the lowest policy priority in the target virtual host
1106+
let existing_policies = client.list_policies_in(vhost)?;
1107+
let min_priority = existing_policies
1108+
.iter()
1109+
.fold(0, |acc, p| if p.priority < acc { p.priority } else { acc });
1110+
1111+
// blanket policy priority should be the lowest in the virtual host
1112+
let priority = [min_priority - 1, DEFAULT_BLANKET_POLICY_PRIORITY]
1113+
.iter()
1114+
.min()
1115+
.cloned()
1116+
.unwrap();
1117+
1118+
let name = command_args.get_one::<String>("name").cloned().unwrap();
1119+
let apply_to = command_args
1120+
.get_one::<PolicyTarget>("apply_to")
1121+
.cloned()
1122+
.unwrap();
1123+
let definition = command_args.get_one::<String>("definition").unwrap();
1124+
1125+
let parsed_definition = serde_json::from_str::<requests::PolicyDefinition>(definition)
1126+
.unwrap_or_else(|err| {
1127+
eprintln!("`{}` is not a valid JSON: {}", definition, err);
1128+
process::exit(1);
1129+
});
1130+
1131+
let params = requests::PolicyParams {
1132+
vhost,
1133+
name: &name,
1134+
pattern: ".*",
1135+
apply_to,
1136+
priority: priority as i32,
1137+
definition: parsed_definition,
1138+
};
1139+
1140+
client.declare_policy(&params)
1141+
}
1142+
10991143
pub fn update_policy_definition(
11001144
client: APIClient,
11011145
vhost: &str,

src/constants.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ pub const DEFAULT_CONFIG_FILE_PATH: &str = "~/.rabbitmqadmin.conf";
3434
pub const DEFAULT_CONFIG_SECTION_NAME: &str = "default";
3535

3636
pub const TANZU_COMMAND_PREFIX: &str = "tanzu";
37+
38+
pub const DEFAULT_BLANKET_POLICY_PRIORITY: i16 = -20;

src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,10 @@ fn dispatch_common_subcommand(
737737
let result = commands::declare_policy_override(client, &vhost, second_level_args);
738738
res_handler.no_output_on_success(result);
739739
}
740+
("policies", "declare_blanket") => {
741+
let result = commands::declare_blanket_policy(client, &vhost, second_level_args);
742+
res_handler.no_output_on_success(result);
743+
}
740744
("policies", "delete") => {
741745
let result = commands::delete_policy(client, &vhost, second_level_args);
742746
res_handler.no_output_on_success(result);

tests/policies_tests.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,3 +646,36 @@ fn test_policies_declare_override() -> Result<(), Box<dyn std::error::Error>> {
646646

647647
Ok(())
648648
}
649+
650+
#[test]
651+
fn test_policies_declare_blanket() -> Result<(), Box<dyn std::error::Error>> {
652+
let policy_name = "test_policies_declare_blanket.1";
653+
654+
run_succeeds([
655+
"policies",
656+
"declare_blanket",
657+
"--name",
658+
policy_name,
659+
"--apply-to",
660+
"queues",
661+
"--definition",
662+
"{\"max-length\": 787876}",
663+
]);
664+
665+
run_succeeds(["policies", "list"]).stdout(
666+
predicate::str::contains(policy_name)
667+
// default blanket policy priority
668+
.and(predicate::str::contains("787876")),
669+
);
670+
671+
let client = api_client();
672+
let pol = client.get_policy("/", policy_name).unwrap();
673+
674+
assert_eq!(pol.pattern, ".*");
675+
assert!(pol.priority < 0);
676+
677+
run_succeeds(["delete", "policy", "--name", policy_name]);
678+
run_succeeds(["policies", "list"]).stdout(predicate::str::contains(policy_name).not());
679+
680+
Ok(())
681+
}

0 commit comments

Comments
 (0)