diff --git a/crates/redisctl/src/cli.rs b/crates/redisctl/src/cli.rs index aae9e1da..0c7e5eb8 100644 --- a/crates/redisctl/src/cli.rs +++ b/crates/redisctl/src/cli.rs @@ -614,6 +614,9 @@ pub enum CloudFixedDatabaseCommands { subscription_id: i32, /// JSON file with database configuration (use @filename or - for stdin) file: String, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// Update fixed database configuration Update { @@ -621,6 +624,9 @@ pub enum CloudFixedDatabaseCommands { id: String, /// JSON file with update configuration (use @filename or - for stdin) file: String, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// Delete a fixed database Delete { @@ -629,6 +635,9 @@ pub enum CloudFixedDatabaseCommands { /// Skip confirmation prompt #[arg(short, long)] yes: bool, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// Get backup status for fixed database #[command(name = "backup-status")] @@ -640,6 +649,9 @@ pub enum CloudFixedDatabaseCommands { Backup { /// Database ID (format: subscription_id:database_id) id: String, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// Get import status #[command(name = "import-status")] @@ -653,6 +665,9 @@ pub enum CloudFixedDatabaseCommands { id: String, /// JSON file with import configuration (use @filename or - for stdin) file: String, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// View slow query log #[command(name = "slow-log")] @@ -749,6 +764,9 @@ pub enum CloudFixedSubscriptionCommands { Create { /// JSON file with subscription configuration (use @filename or - for stdin) file: String, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// Update fixed subscription Update { @@ -756,6 +774,9 @@ pub enum CloudFixedSubscriptionCommands { id: i32, /// JSON file with update configuration (use @filename or - for stdin) file: String, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// Delete a fixed subscription Delete { @@ -764,6 +785,9 @@ pub enum CloudFixedSubscriptionCommands { /// Skip confirmation prompt #[arg(short, long)] yes: bool, + /// Async operation options + #[command(flatten)] + async_ops: crate::commands::cloud::async_utils::AsyncOperationArgs, }, /// Get available Redis versions for fixed subscription #[command(name = "redis-versions")] diff --git a/crates/redisctl/src/commands/cloud/fixed_database.rs b/crates/redisctl/src/commands/cloud/fixed_database.rs index 3d6ecb61..7111a7eb 100644 --- a/crates/redisctl/src/commands/cloud/fixed_database.rs +++ b/crates/redisctl/src/commands/cloud/fixed_database.rs @@ -3,6 +3,7 @@ #![allow(dead_code)] use crate::cli::{CloudFixedDatabaseCommands, OutputFormat}; +use crate::commands::cloud::async_utils::handle_async_response; use crate::commands::cloud::utils::{ confirm_action, handle_output, print_formatted_output, read_file_input, }; @@ -83,6 +84,7 @@ pub async fn handle_fixed_database_command( CloudFixedDatabaseCommands::Create { subscription_id, file, + async_ops, } => { let json_string = read_file_input(file)?; let request: FixedDatabaseCreateRequest = @@ -93,23 +95,26 @@ pub async fn handle_fixed_database_command( .await .context("Failed to create fixed database")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!("Fixed database creation initiated. Task ID: {}", task_id); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Fixed database created successfully", + ) + .await } - CloudFixedDatabaseCommands::Update { id, file } => { + CloudFixedDatabaseCommands::Update { + id, + file, + async_ops, + } => { let (subscription_id, database_id) = parse_fixed_database_id(id)?; let json_string = read_file_input(file)?; let request: FixedDatabaseUpdateRequest = @@ -120,23 +125,22 @@ pub async fn handle_fixed_database_command( .await .context("Failed to update fixed database")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!("Fixed database update initiated. Task ID: {}", task_id); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Fixed database updated successfully", + ) + .await } - CloudFixedDatabaseCommands::Delete { id, yes } => { + CloudFixedDatabaseCommands::Delete { id, yes, async_ops } => { let (subscription_id, database_id) = parse_fixed_database_id(id)?; if !yes { @@ -152,22 +156,19 @@ pub async fn handle_fixed_database_command( .await .context("Failed to delete fixed database")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!("Fixed database deletion initiated. Task ID: {}", task_id); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } else { - eprintln!("Fixed database deleted successfully"); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Fixed database deleted successfully", + ) + .await } CloudFixedDatabaseCommands::BackupStatus { id } => { @@ -184,7 +185,7 @@ pub async fn handle_fixed_database_command( Ok(()) } - CloudFixedDatabaseCommands::Backup { id } => { + CloudFixedDatabaseCommands::Backup { id, async_ops } => { let (subscription_id, database_id) = parse_fixed_database_id(id)?; // Create a minimal backup request - most fields are optional @@ -201,20 +202,19 @@ pub async fn handle_fixed_database_command( .await .context("Failed to initiate backup")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!("Backup initiated. Task ID: {}", task_id); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Backup initiated successfully", + ) + .await } CloudFixedDatabaseCommands::ImportStatus { id } => { @@ -231,7 +231,11 @@ pub async fn handle_fixed_database_command( Ok(()) } - CloudFixedDatabaseCommands::Import { id, file } => { + CloudFixedDatabaseCommands::Import { + id, + file, + async_ops, + } => { let (subscription_id, database_id) = parse_fixed_database_id(id)?; let json_string = read_file_input(file)?; let request: FixedDatabaseImportRequest = @@ -242,20 +246,19 @@ pub async fn handle_fixed_database_command( .await .context("Failed to initiate import")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!("Import initiated. Task ID: {}", task_id); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Import initiated successfully", + ) + .await } CloudFixedDatabaseCommands::SlowLog { diff --git a/crates/redisctl/src/commands/cloud/fixed_subscription.rs b/crates/redisctl/src/commands/cloud/fixed_subscription.rs index 73d3cfa5..29a3d87d 100644 --- a/crates/redisctl/src/commands/cloud/fixed_subscription.rs +++ b/crates/redisctl/src/commands/cloud/fixed_subscription.rs @@ -3,6 +3,7 @@ #![allow(dead_code)] use crate::cli::{CloudFixedSubscriptionCommands, OutputFormat}; +use crate::commands::cloud::async_utils::handle_async_response; use crate::commands::cloud::utils::{ confirm_action, handle_output, print_formatted_output, read_file_input, }; @@ -117,7 +118,7 @@ pub async fn handle_fixed_subscription_command( Ok(()) } - CloudFixedSubscriptionCommands::Create { file } => { + CloudFixedSubscriptionCommands::Create { file, async_ops } => { let json_string = read_file_input(file)?; let request: FixedSubscriptionCreateRequest = serde_json::from_str(&json_string).context("Invalid subscription configuration")?; @@ -127,26 +128,26 @@ pub async fn handle_fixed_subscription_command( .await .context("Failed to create fixed subscription")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!( - "Fixed subscription creation initiated. Task ID: {}", - task_id - ); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Fixed subscription created successfully", + ) + .await } - CloudFixedSubscriptionCommands::Update { id, file } => { + CloudFixedSubscriptionCommands::Update { + id, + file, + async_ops, + } => { let json_string = read_file_input(file)?; let request: FixedSubscriptionUpdateRequest = serde_json::from_str(&json_string).context("Invalid update configuration")?; @@ -156,23 +157,22 @@ pub async fn handle_fixed_subscription_command( .await .context("Failed to update fixed subscription")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!("Fixed subscription update initiated. Task ID: {}", task_id); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Fixed subscription updated successfully", + ) + .await } - CloudFixedSubscriptionCommands::Delete { id, yes } => { + CloudFixedSubscriptionCommands::Delete { id, yes, async_ops } => { if !yes { let prompt = format!("Delete fixed subscription {}?", id); if !confirm_action(&prompt)? { @@ -186,25 +186,19 @@ pub async fn handle_fixed_subscription_command( .await .context("Failed to delete fixed subscription")?; - // Check if response contains a task ID let json_result = serde_json::to_value(&result).context("Failed to serialize response")?; - if let Some(task_id) = json_result.get("taskId").and_then(|v| v.as_str()) { - eprintln!( - "Fixed subscription deletion initiated. Task ID: {}", - task_id - ); - eprintln!( - "Use 'redisctl cloud task wait {}' to monitor progress", - task_id - ); - } else { - eprintln!("Fixed subscription deleted successfully"); - } - let data = handle_output(json_result, output_format, query)?; - print_formatted_output(data, output_format)?; - Ok(()) + handle_async_response( + conn_mgr, + profile_name, + json_result, + async_ops, + output_format, + query, + "Fixed subscription deleted successfully", + ) + .await } CloudFixedSubscriptionCommands::RedisVersions { subscription } => {