Skip to content

Commit 8998f1c

Browse files
'definitions export_from_vhost' now supports --transformations
Closes #82.
1 parent 0827b50 commit 8998f1c

File tree

4 files changed

+136
-8
lines changed

4 files changed

+136
-8
lines changed

src/cli.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2253,6 +2253,41 @@ Examples:
22532253
.num_args(0)
22542254
.action(ArgAction::SetTrue)
22552255
.conflicts_with("file"),
2256+
)
2257+
.arg(
2258+
Arg::new("transformations")
2259+
.long("transformations")
2260+
.short('t')
2261+
.long_help(
2262+
r#"
2263+
A comma-separated list of names of the definition transformations to apply.
2264+
2265+
Supported transformations:
2266+
2267+
* no_op
2268+
* prepare_for_quorum_queue_migration
2269+
* strip_cmq_keys_from_policies
2270+
* drop_empty_policies
2271+
* obfuscate_usernames
2272+
* exclude_users
2273+
* exclude_permissions
2274+
* exclude_runtime_parameters
2275+
* exclude_policies
2276+
2277+
Examples:
2278+
2279+
* --transformations prepare_for_quorum_queue_migration,drop_empty_policies
2280+
* --transformations strip_cmq_keys_from_policies,drop_empty_policies
2281+
* --transformations exclude_users,exclude_permissions
2282+
* --transformations obfuscate_usernames
2283+
* --transformations exclude_runtime_parameters,exclude_policies
2284+
* --transformations no_op
2285+
"#,
2286+
)
2287+
.num_args(1..)
2288+
.value_delimiter(',')
2289+
.action(ArgAction::Append)
2290+
.required(false),
22562291
);
22572292

22582293
let import_cmd = Command::new("import")

src/commands.rs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rabbitmq_http_client::requests::{
3333
RuntimeParameterDefinition,
3434
};
3535
use rabbitmq_http_client::responses::OptionalArgumentSourceOps;
36-
use rabbitmq_http_client::transformers::TransformationChain;
36+
use rabbitmq_http_client::transformers::{TransformationChain, VirtualHostTransformationChain};
3737
use rabbitmq_http_client::{password_hashing, requests, responses};
3838
use serde::de::DeserializeOwned;
3939
use serde_json::Value;
@@ -1638,7 +1638,54 @@ pub fn export_vhost_definitions(
16381638
client: APIClient,
16391639
vhost: &str,
16401640
command_args: &ArgMatches,
1641-
) -> ClientResult<()> {
1641+
) -> Result<(), CommandRunError> {
1642+
let transformations = command_args
1643+
.get_many::<String>("transformations")
1644+
.unwrap_or_default();
1645+
1646+
if transformations.len() == 0 {
1647+
export_vhost_definitions_without_transformations(client, vhost, command_args)
1648+
} else {
1649+
let transformations = transformations.map(String::from).collect();
1650+
1651+
export_and_transform_vhost_definitions(client, vhost, command_args, transformations)
1652+
}
1653+
}
1654+
1655+
fn export_and_transform_vhost_definitions(
1656+
client: APIClient,
1657+
vhost: &str,
1658+
command_args: &ArgMatches,
1659+
transformations: Vec<String>,
1660+
) -> Result<(), CommandRunError> {
1661+
match client.export_vhost_definitions_as_data(vhost) {
1662+
Ok(mut defs0) => {
1663+
let chain = VirtualHostTransformationChain::from(transformations);
1664+
chain.apply(&mut defs0);
1665+
1666+
let json = serde_json::to_string_pretty(&defs0).unwrap();
1667+
1668+
let path = command_args.get_one::<String>("file").unwrap();
1669+
match path.as_str() {
1670+
"-" => {
1671+
println!("{}", &json);
1672+
Ok(())
1673+
}
1674+
file => {
1675+
fs::write(file, &json)?;
1676+
Ok(())
1677+
}
1678+
}
1679+
}
1680+
Err(err) => Err(err.into()),
1681+
}
1682+
}
1683+
1684+
fn export_vhost_definitions_without_transformations(
1685+
client: APIClient,
1686+
vhost: &str,
1687+
command_args: &ArgMatches,
1688+
) -> Result<(), CommandRunError> {
16421689
match client.export_vhost_definitions(vhost) {
16431690
Ok(definitions) => {
16441691
let path = command_args.get_one::<String>("file").unwrap();
@@ -1648,12 +1695,12 @@ pub fn export_vhost_definitions(
16481695
Ok(())
16491696
}
16501697
file => {
1651-
_ = fs::write(file, &definitions);
1698+
fs::write(file, &definitions)?;
16521699
Ok(())
16531700
}
16541701
}
16551702
}
1656-
Err(err) => Err(err),
1703+
Err(err) => Err(err.into()),
16571704
}
16581705
}
16591706

src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,7 @@ fn dispatch_common_subcommand(
517517
res_handler.no_output_on_success(result);
518518
}
519519
("definitions", "export_from_vhost") => {
520-
let result = commands::export_vhost_definitions(client, &vhost, second_level_args)
521-
.map_err(Into::into);
520+
let result = commands::export_vhost_definitions(client, &vhost, second_level_args);
522521
res_handler.no_output_on_success(result);
523522
}
524523
("definitions", "import") => {

tests/definitions_export_tests.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,62 @@ fn test_export_cluster_wide_definitions_with_transformations_case1()
7878

7979
run_succeeds(["--vhost", vh, "definitions", "export"]).stdout(predicate::str::contains(p1));
8080
// These two cannot be tested on 4.x: empty definitions will be rejected
81-
// by validation and CMQ keys are no longer recognized as known/valid.
81+
// by validation, and CMQ keys are no longer recognized as known/valid.
8282
// But at least we can test the code path this way.
8383
run_succeeds([
8484
"--vhost",
8585
vh,
8686
"definitions",
8787
"export",
8888
"--transformations",
89-
"strip_cmq_keys_from_policies,drop_empty_policies",
89+
"prepare_for_quorum_queue_migration,strip_cmq_keys_from_policies,drop_empty_policies",
90+
])
91+
.stdout(predicate::str::contains(p1));
92+
93+
delete_vhost(vh).expect("failed to delete a virtual host");
94+
95+
Ok(())
96+
}
97+
98+
#[test]
99+
fn test_export_vhost_definitions_with_transformations_case1()
100+
-> Result<(), Box<dyn std::error::Error>> {
101+
let vh = "test_export_vhost_definitions.transformations.1";
102+
delete_vhost(vh).expect("failed to delete a virtual host");
103+
run_succeeds(["declare", "vhost", "--name", vh]);
104+
105+
let p1 = "test_export_vhost_definitions.transformations.1";
106+
run_succeeds([
107+
"--vhost",
108+
vh,
109+
"declare",
110+
"policy",
111+
"--name",
112+
p1,
113+
"--pattern",
114+
"^matching\\..+",
115+
"--apply-to",
116+
"classic_queues",
117+
"--priority",
118+
"10",
119+
"--definition",
120+
"{\"max-length\": 10}",
121+
]);
122+
123+
let q = "qq.test_export_vhost_definitions.transformations.1";
124+
run_succeeds([
125+
"-V", vh, "declare", "queue", "--name", q, "--type", "quorum",
126+
]);
127+
128+
run_succeeds(["--vhost", vh, "definitions", "export_from_vhost"])
129+
.stdout(predicate::str::contains(p1));
130+
run_succeeds([
131+
"--vhost",
132+
vh,
133+
"definitions",
134+
"export_from_vhost",
135+
"--transformations",
136+
"prepare_for_quorum_queue_migration,strip_cmq_keys_from_policies,drop_empty_policies",
90137
])
91138
.stdout(predicate::str::contains(p1));
92139

0 commit comments

Comments
 (0)