Skip to content

Commit d86dca4

Browse files
Merge pull request #200 from joshrotenberg/feat/user-provider-wait-flag
feat(redisctl): add --wait flag support for Cloud user and provider account operations
2 parents eb6d49f + 9599964 commit d86dca4

File tree

4 files changed

+136
-36
lines changed

4 files changed

+136
-36
lines changed

crates/redisctl/src/cli.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,9 @@ pub enum CloudProviderAccountCommands {
858858
/// For GCP, this should be the service account JSON file
859859
/// Use @filename to read from file
860860
file: String,
861+
/// Async operation arguments
862+
#[command(flatten)]
863+
async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs,
861864
},
862865
/// Update a cloud provider account
863866
Update {
@@ -866,6 +869,9 @@ pub enum CloudProviderAccountCommands {
866869
/// JSON file containing updated cloud account configuration
867870
/// Use @filename to read from file
868871
file: String,
872+
/// Async operation arguments
873+
#[command(flatten)]
874+
async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs,
869875
},
870876
/// Delete a cloud provider account
871877
Delete {
@@ -874,6 +880,9 @@ pub enum CloudProviderAccountCommands {
874880
/// Skip confirmation prompt
875881
#[arg(long)]
876882
force: bool,
883+
/// Async operation arguments
884+
#[command(flatten)]
885+
async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs,
877886
},
878887
}
879888

@@ -1321,6 +1330,9 @@ pub enum CloudUserCommands {
13211330
/// Skip confirmation prompt
13221331
#[arg(long)]
13231332
force: bool,
1333+
/// Async operation arguments
1334+
#[command(flatten)]
1335+
async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs,
13241336
},
13251337
}
13261338

crates/redisctl/src/commands/cloud/cloud_account.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![allow(dead_code)]
22

33
use crate::cli::{CloudProviderAccountCommands, OutputFormat};
4-
use crate::commands::cloud::cloud_account_impl;
4+
use crate::commands::cloud::cloud_account_impl::{self, CloudAccountOperationParams};
55
use crate::commands::cloud::utils::create_cloud_client_raw;
66
use crate::connection::ConnectionManager;
77
use crate::error::Result as CliResult;
@@ -23,15 +23,46 @@ pub async fn handle_cloud_account_command(
2323
CloudProviderAccountCommands::Get { account_id } => {
2424
cloud_account_impl::handle_get(&client, *account_id, output_format, query).await
2525
}
26-
CloudProviderAccountCommands::Create { file } => {
27-
cloud_account_impl::handle_create(&client, file, output_format, query).await
26+
CloudProviderAccountCommands::Create { file, async_ops } => {
27+
let params = CloudAccountOperationParams {
28+
conn_mgr,
29+
profile_name,
30+
client: &client,
31+
async_ops,
32+
output_format,
33+
query,
34+
};
35+
cloud_account_impl::handle_create(&params, file).await
2836
}
29-
CloudProviderAccountCommands::Update { account_id, file } => {
30-
cloud_account_impl::handle_update(&client, *account_id, file, output_format, query)
31-
.await
37+
CloudProviderAccountCommands::Update {
38+
account_id,
39+
file,
40+
async_ops,
41+
} => {
42+
let params = CloudAccountOperationParams {
43+
conn_mgr,
44+
profile_name,
45+
client: &client,
46+
async_ops,
47+
output_format,
48+
query,
49+
};
50+
cloud_account_impl::handle_update(&params, *account_id, file).await
3251
}
33-
CloudProviderAccountCommands::Delete { account_id, force } => {
34-
cloud_account_impl::handle_delete(&client, *account_id, *force).await
52+
CloudProviderAccountCommands::Delete {
53+
account_id,
54+
force,
55+
async_ops,
56+
} => {
57+
let params = CloudAccountOperationParams {
58+
conn_mgr,
59+
profile_name,
60+
client: &client,
61+
async_ops,
62+
output_format,
63+
query,
64+
};
65+
cloud_account_impl::handle_delete(&params, *account_id, *force).await
3566
}
3667
}
3768
}

crates/redisctl/src/commands/cloud/cloud_account_impl.rs

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
#![allow(dead_code)]
22

33
use crate::cli::OutputFormat;
4+
use crate::commands::cloud::async_utils::{AsyncOperationArgs, handle_async_response};
45
use crate::commands::cloud::utils::{
56
confirm_action, handle_output, print_formatted_output, read_file_input,
67
};
8+
use crate::connection::ConnectionManager;
79
use crate::error::Result as CliResult;
810

911
use anyhow::Context;
1012
use comfy_table::{Cell, Color, Table};
1113
use redis_cloud::CloudClient;
1214
use serde_json::{Value, json};
1315

16+
/// Parameters for cloud account operations that support async operations
17+
pub struct CloudAccountOperationParams<'a> {
18+
pub conn_mgr: &'a ConnectionManager,
19+
pub profile_name: Option<&'a str>,
20+
pub client: &'a CloudClient,
21+
pub async_ops: &'a AsyncOperationArgs,
22+
pub output_format: OutputFormat,
23+
pub query: Option<&'a str>,
24+
}
25+
1426
pub async fn handle_list(
1527
client: &CloudClient,
1628
output_format: OutputFormat,
@@ -107,12 +119,7 @@ pub async fn handle_get(
107119
Ok(())
108120
}
109121

110-
pub async fn handle_create(
111-
client: &CloudClient,
112-
file: &str,
113-
output_format: OutputFormat,
114-
query: Option<&str>,
115-
) -> CliResult<()> {
122+
pub async fn handle_create(params: &CloudAccountOperationParams<'_>, file: &str) -> CliResult<()> {
116123
let content = read_file_input(file)?;
117124
let mut payload: Value =
118125
serde_json::from_str(&content).context("Failed to parse JSON from file")?;
@@ -175,38 +182,56 @@ pub async fn handle_create(
175182
}
176183
}
177184

178-
let result = client
185+
let response = params
186+
.client
179187
.post_raw("/cloud-accounts", payload)
180188
.await
181189
.context("Failed to create cloud account")?;
182190

183-
let data = handle_output(result, output_format, query)?;
184-
print_formatted_output(data, output_format)?;
185-
Ok(())
191+
handle_async_response(
192+
params.conn_mgr,
193+
params.profile_name,
194+
response,
195+
params.async_ops,
196+
params.output_format,
197+
params.query,
198+
"cloud account creation",
199+
)
200+
.await
186201
}
187202

188203
pub async fn handle_update(
189-
client: &CloudClient,
204+
params: &CloudAccountOperationParams<'_>,
190205
account_id: i32,
191206
file: &str,
192-
output_format: OutputFormat,
193-
query: Option<&str>,
194207
) -> CliResult<()> {
195208
let content = read_file_input(file)?;
196209
let payload: Value =
197210
serde_json::from_str(&content).context("Failed to parse JSON from file")?;
198211

199-
let result = client
212+
let response = params
213+
.client
200214
.put_raw(&format!("/cloud-accounts/{}", account_id), payload)
201215
.await
202216
.context("Failed to update cloud account")?;
203217

204-
let data = handle_output(result, output_format, query)?;
205-
print_formatted_output(data, output_format)?;
206-
Ok(())
218+
handle_async_response(
219+
params.conn_mgr,
220+
params.profile_name,
221+
response,
222+
params.async_ops,
223+
params.output_format,
224+
params.query,
225+
"cloud account update",
226+
)
227+
.await
207228
}
208229

209-
pub async fn handle_delete(client: &CloudClient, account_id: i32, force: bool) -> CliResult<()> {
230+
pub async fn handle_delete(
231+
params: &CloudAccountOperationParams<'_>,
232+
account_id: i32,
233+
force: bool,
234+
) -> CliResult<()> {
210235
if !force {
211236
let confirmed = confirm_action(&format!("delete cloud account {}", account_id))?;
212237
if !confirmed {
@@ -215,11 +240,20 @@ pub async fn handle_delete(client: &CloudClient, account_id: i32, force: bool) -
215240
}
216241
}
217242

218-
client
243+
let response = params
244+
.client
219245
.delete_raw(&format!("/cloud-accounts/{}", account_id))
220246
.await
221247
.context("Failed to delete cloud account")?;
222248

223-
println!("Cloud account {} deleted successfully", account_id);
224-
Ok(())
249+
handle_async_response(
250+
params.conn_mgr,
251+
params.profile_name,
252+
response,
253+
params.async_ops,
254+
params.output_format,
255+
params.query,
256+
"cloud account deletion",
257+
)
258+
.await
225259
}

crates/redisctl/src/commands/cloud/user.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![allow(dead_code)] // Used by binary target
44

5+
use super::async_utils::{AsyncOperationArgs, handle_async_response};
56
use super::utils::DetailRow;
67
use super::utils::*;
78
use crate::cli::{CloudUserCommands, OutputFormat};
@@ -46,8 +47,21 @@ pub async fn handle_user_command(
4647
)
4748
.await
4849
}
49-
CloudUserCommands::Delete { id, force } => {
50-
delete_user(conn_mgr, profile_name, *id, *force, output_format, query).await
50+
CloudUserCommands::Delete {
51+
id,
52+
force,
53+
async_ops,
54+
} => {
55+
delete_user(
56+
conn_mgr,
57+
profile_name,
58+
*id,
59+
*force,
60+
async_ops,
61+
output_format,
62+
query,
63+
)
64+
.await
5165
}
5266
}
5367
}
@@ -537,8 +551,9 @@ async fn delete_user(
537551
profile_name: Option<&str>,
538552
user_id: u32,
539553
force: bool,
540-
_output_format: OutputFormat,
541-
_query: Option<&str>,
554+
async_ops: &AsyncOperationArgs,
555+
output_format: OutputFormat,
556+
query: Option<&str>,
542557
) -> CliResult<()> {
543558
// Confirm deletion unless forced
544559
if !force {
@@ -557,11 +572,19 @@ async fn delete_user(
557572
let client = conn_mgr.create_cloud_client(profile_name).await?;
558573

559574
// Send delete request
560-
client
575+
let response = client
561576
.delete_raw(&format!("/users/{}", user_id))
562577
.await
563578
.context("Failed to delete user")?;
564579

565-
println!("User {} deleted successfully", user_id);
566-
Ok(())
580+
handle_async_response(
581+
conn_mgr,
582+
profile_name,
583+
response,
584+
async_ops,
585+
output_format,
586+
query,
587+
"user deletion",
588+
)
589+
.await
567590
}

0 commit comments

Comments
 (0)