Skip to content

Commit ce1c8a5

Browse files
feat(cloud): add task list, database flush, and available-versions commands (#477)
* feat(cloud): add task list, database flush, and available-versions commands - Add 'cloud task list' command to list all tasks (#465) - Add 'cloud database flush' for standard databases (#467) - Add 'cloud database available-versions' for upgrade planning (#466) - Add library methods for available-target-versions endpoint (Pro and Essentials) - Add library method for standard database flush Closes #465, #466, #467 * chore: re-trigger CI (disk space issue) * chore: retrigger CI * chore: retrigger CI after cache cleanup
1 parent 94cdfdd commit ce1c8a5

File tree

7 files changed

+344
-1
lines changed

7 files changed

+344
-1
lines changed

crates/redis-cloud/src/fixed/databases.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,4 +1197,25 @@ impl FixedDatabaseHandler {
11971197
) -> Result<CloudTags> {
11981198
self.get_tags(subscription_id, database_id).await
11991199
}
1200+
1201+
// ========================================================================
1202+
// New endpoints
1203+
// ========================================================================
1204+
1205+
/// Get available target Redis versions for upgrade
1206+
/// Gets a list of Redis versions that the Essentials database can be upgraded to.
1207+
///
1208+
/// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/available-target-versions
1209+
pub async fn get_available_target_versions(
1210+
&self,
1211+
subscription_id: i32,
1212+
database_id: i32,
1213+
) -> Result<Value> {
1214+
self.client
1215+
.get_raw(&format!(
1216+
"/fixed/subscriptions/{}/databases/{}/available-target-versions",
1217+
subscription_id, database_id
1218+
))
1219+
.await
1220+
}
12001221
}

crates/redis-cloud/src/flexible/databases.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,4 +1548,43 @@ impl DatabaseHandler {
15481548
)
15491549
.await
15501550
}
1551+
1552+
/// Get available target Redis versions for upgrade
1553+
/// Gets a list of Redis versions that the database can be upgraded to.
1554+
///
1555+
/// GET /subscriptions/{subscriptionId}/databases/{databaseId}/available-target-versions
1556+
pub async fn get_available_target_versions(
1557+
&self,
1558+
subscription_id: i32,
1559+
database_id: i32,
1560+
) -> Result<Value> {
1561+
self.client
1562+
.get_raw(&format!(
1563+
"/subscriptions/{}/databases/{}/available-target-versions",
1564+
subscription_id, database_id
1565+
))
1566+
.await
1567+
}
1568+
1569+
/// Flush Pro database (standard, non-Active-Active)
1570+
/// Deletes all data from the specified Pro database.
1571+
///
1572+
/// PUT /subscriptions/{subscriptionId}/databases/{databaseId}/flush
1573+
pub async fn flush_database(
1574+
&self,
1575+
subscription_id: i32,
1576+
database_id: i32,
1577+
) -> Result<TaskStateUpdate> {
1578+
// Empty body for standard flush
1579+
self.client
1580+
.put_raw(
1581+
&format!(
1582+
"/subscriptions/{}/databases/{}/flush",
1583+
subscription_id, database_id
1584+
),
1585+
serde_json::json!({}),
1586+
)
1587+
.await
1588+
.and_then(|v| serde_json::from_value(v).map_err(Into::into))
1589+
}
15511590
}

crates/redis-cloud/src/tasks.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,18 @@ impl TasksHandler {
160160
/// Gets a list of all currently running tasks for this account.
161161
///
162162
/// GET /tasks
163-
pub async fn get_all_tasks(&self) -> Result<()> {
163+
pub async fn get_all_tasks(&self) -> Result<Vec<TaskStateUpdate>> {
164164
self.client.get("/tasks").await
165165
}
166166

167+
/// Get tasks (raw JSON)
168+
/// Gets a list of all currently running tasks for this account.
169+
///
170+
/// GET /tasks
171+
pub async fn get_all_tasks_raw(&self) -> Result<serde_json::Value> {
172+
self.client.get_raw("/tasks").await
173+
}
174+
167175
/// Get a single task
168176
/// Gets details and status of a single task by the Task ID.
169177
///

crates/redisctl/src/cli/cloud.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ pub enum PrivateLinkCommands {
485485
/// Cloud Task Commands
486486
#[derive(Subcommand, Debug)]
487487
pub enum CloudTaskCommands {
488+
/// List all tasks for this account
489+
#[command(alias = "ls")]
490+
List,
488491
/// Get task status and details
489492
Get {
490493
/// Task ID (UUID format)
@@ -1335,6 +1338,15 @@ pub enum CloudDatabaseCommands {
13351338
key: String,
13361339
},
13371340

1341+
/// Flush database (deletes all data)
1342+
Flush {
1343+
/// Database ID (format: subscription_id:database_id)
1344+
id: String,
1345+
/// Skip confirmation prompt
1346+
#[arg(long)]
1347+
force: bool,
1348+
},
1349+
13381350
/// Flush Active-Active database
13391351
FlushCrdb {
13401352
/// Database ID (format: subscription_id:database_id)
@@ -1344,6 +1356,12 @@ pub enum CloudDatabaseCommands {
13441356
force: bool,
13451357
},
13461358

1359+
/// Get available Redis versions for upgrade
1360+
AvailableVersions {
1361+
/// Database ID (format: subscription_id:database_id)
1362+
id: String,
1363+
},
1364+
13471365
/// Get Redis version upgrade status
13481366
UpgradeStatus {
13491367
/// Database ID (format: subscription_id:database_id)

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ pub async fn handle_database_command(
209209
super::database_impl::delete_tag(conn_mgr, profile_name, id, key, output_format, query)
210210
.await
211211
}
212+
CloudDatabaseCommands::Flush { id, force } => {
213+
super::database_impl::flush_database(
214+
conn_mgr,
215+
profile_name,
216+
id,
217+
*force,
218+
output_format,
219+
query,
220+
)
221+
.await
222+
}
212223
CloudDatabaseCommands::FlushCrdb { id, force } => {
213224
super::database_impl::flush_crdb(
214225
conn_mgr,
@@ -220,6 +231,16 @@ pub async fn handle_database_command(
220231
)
221232
.await
222233
}
234+
CloudDatabaseCommands::AvailableVersions { id } => {
235+
super::database_impl::get_available_versions(
236+
conn_mgr,
237+
profile_name,
238+
id,
239+
output_format,
240+
query,
241+
)
242+
.await
243+
}
223244
CloudDatabaseCommands::UpgradeStatus { id } => {
224245
super::database_impl::get_upgrade_status(
225246
conn_mgr,

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

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,119 @@ pub async fn delete_tag(
713713
Ok(())
714714
}
715715

716+
/// Flush standard (non-Active-Active) database
717+
pub async fn flush_database(
718+
conn_mgr: &ConnectionManager,
719+
profile_name: Option<&str>,
720+
id: &str,
721+
force: bool,
722+
output_format: OutputFormat,
723+
query: Option<&str>,
724+
) -> CliResult<()> {
725+
let (subscription_id, database_id) = parse_database_id(id)?;
726+
727+
// Confirmation prompt unless --force is used
728+
if !force {
729+
use dialoguer::Confirm;
730+
let confirm = Confirm::new()
731+
.with_prompt(format!(
732+
"Are you sure you want to flush database {}? This will delete all data!",
733+
id
734+
))
735+
.default(false)
736+
.interact()
737+
.map_err(|e| RedisCtlError::InvalidInput {
738+
message: format!("Failed to read confirmation: {}", e),
739+
})?;
740+
741+
if !confirm {
742+
println!("Flush operation cancelled");
743+
return Ok(());
744+
}
745+
}
746+
747+
let client = conn_mgr.create_cloud_client(profile_name).await?;
748+
749+
let response = client
750+
.put_raw(
751+
&format!(
752+
"/subscriptions/{}/databases/{}/flush",
753+
subscription_id, database_id
754+
),
755+
json!({}),
756+
)
757+
.await
758+
.context("Failed to flush database")?;
759+
760+
let result = if let Some(q) = query {
761+
apply_jmespath(&response, q)?
762+
} else {
763+
response
764+
};
765+
766+
match output_format {
767+
OutputFormat::Table => {
768+
println!("Database flush initiated");
769+
if let Some(task_id) = result.get("taskId") {
770+
println!("Task ID: {}", task_id);
771+
}
772+
}
773+
_ => print_json_or_yaml(result, output_format)?,
774+
}
775+
776+
Ok(())
777+
}
778+
779+
/// Get available Redis versions for upgrade
780+
pub async fn get_available_versions(
781+
conn_mgr: &ConnectionManager,
782+
profile_name: Option<&str>,
783+
id: &str,
784+
output_format: OutputFormat,
785+
query: Option<&str>,
786+
) -> CliResult<()> {
787+
let (subscription_id, database_id) = parse_database_id(id)?;
788+
let client = conn_mgr.create_cloud_client(profile_name).await?;
789+
790+
let response = client
791+
.get_raw(&format!(
792+
"/subscriptions/{}/databases/{}/available-target-versions",
793+
subscription_id, database_id
794+
))
795+
.await
796+
.context("Failed to get available versions")?;
797+
798+
let result = if let Some(q) = query {
799+
apply_jmespath(&response, q)?
800+
} else {
801+
response
802+
};
803+
804+
match output_format {
805+
OutputFormat::Table => {
806+
if let Some(versions) = result.as_array() {
807+
if versions.is_empty() {
808+
println!("No upgrade versions available");
809+
} else {
810+
println!("Available Redis versions for upgrade:");
811+
for v in versions {
812+
if let Some(version) = v.as_str() {
813+
println!(" - {}", version);
814+
} else {
815+
println!(" - {}", v);
816+
}
817+
}
818+
}
819+
} else {
820+
print_json_or_yaml(result, output_format)?;
821+
}
822+
}
823+
_ => print_json_or_yaml(result, output_format)?,
824+
}
825+
826+
Ok(())
827+
}
828+
716829
/// Flush Active-Active database
717830
pub async fn flush_crdb(
718831
conn_mgr: &ConnectionManager,

0 commit comments

Comments
 (0)