Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions crates/redis-cloud/src/fixed/databases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,4 +1197,25 @@ impl FixedDatabaseHandler {
) -> Result<CloudTags> {
self.get_tags(subscription_id, database_id).await
}

// ========================================================================
// New endpoints
// ========================================================================

/// Get available target Redis versions for upgrade
/// Gets a list of Redis versions that the Essentials database can be upgraded to.
///
/// GET /fixed/subscriptions/{subscriptionId}/databases/{databaseId}/available-target-versions
pub async fn get_available_target_versions(
&self,
subscription_id: i32,
database_id: i32,
) -> Result<Value> {
self.client
.get_raw(&format!(
"/fixed/subscriptions/{}/databases/{}/available-target-versions",
subscription_id, database_id
))
.await
}
}
39 changes: 39 additions & 0 deletions crates/redis-cloud/src/flexible/databases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1548,4 +1548,43 @@ impl DatabaseHandler {
)
.await
}

/// Get available target Redis versions for upgrade
/// Gets a list of Redis versions that the database can be upgraded to.
///
/// GET /subscriptions/{subscriptionId}/databases/{databaseId}/available-target-versions
pub async fn get_available_target_versions(
&self,
subscription_id: i32,
database_id: i32,
) -> Result<Value> {
self.client
.get_raw(&format!(
"/subscriptions/{}/databases/{}/available-target-versions",
subscription_id, database_id
))
.await
}

/// Flush Pro database (standard, non-Active-Active)
/// Deletes all data from the specified Pro database.
///
/// PUT /subscriptions/{subscriptionId}/databases/{databaseId}/flush
pub async fn flush_database(
&self,
subscription_id: i32,
database_id: i32,
) -> Result<TaskStateUpdate> {
// Empty body for standard flush
self.client
.put_raw(
&format!(
"/subscriptions/{}/databases/{}/flush",
subscription_id, database_id
),
serde_json::json!({}),
)
.await
.and_then(|v| serde_json::from_value(v).map_err(Into::into))
}
}
10 changes: 9 additions & 1 deletion crates/redis-cloud/src/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,18 @@ impl TasksHandler {
/// Gets a list of all currently running tasks for this account.
///
/// GET /tasks
pub async fn get_all_tasks(&self) -> Result<()> {
pub async fn get_all_tasks(&self) -> Result<Vec<TaskStateUpdate>> {
self.client.get("/tasks").await
}

/// Get tasks (raw JSON)
/// Gets a list of all currently running tasks for this account.
///
/// GET /tasks
pub async fn get_all_tasks_raw(&self) -> Result<serde_json::Value> {
self.client.get_raw("/tasks").await
}

/// Get a single task
/// Gets details and status of a single task by the Task ID.
///
Expand Down
18 changes: 18 additions & 0 deletions crates/redisctl/src/cli/cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,9 @@ pub enum PrivateLinkCommands {
/// Cloud Task Commands
#[derive(Subcommand, Debug)]
pub enum CloudTaskCommands {
/// List all tasks for this account
#[command(alias = "ls")]
List,
/// Get task status and details
Get {
/// Task ID (UUID format)
Expand Down Expand Up @@ -1335,6 +1338,15 @@ pub enum CloudDatabaseCommands {
key: String,
},

/// Flush database (deletes all data)
Flush {
/// Database ID (format: subscription_id:database_id)
id: String,
/// Skip confirmation prompt
#[arg(long)]
force: bool,
},

/// Flush Active-Active database
FlushCrdb {
/// Database ID (format: subscription_id:database_id)
Expand All @@ -1344,6 +1356,12 @@ pub enum CloudDatabaseCommands {
force: bool,
},

/// Get available Redis versions for upgrade
AvailableVersions {
/// Database ID (format: subscription_id:database_id)
id: String,
},

/// Get Redis version upgrade status
UpgradeStatus {
/// Database ID (format: subscription_id:database_id)
Expand Down
21 changes: 21 additions & 0 deletions crates/redisctl/src/commands/cloud/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ pub async fn handle_database_command(
super::database_impl::delete_tag(conn_mgr, profile_name, id, key, output_format, query)
.await
}
CloudDatabaseCommands::Flush { id, force } => {
super::database_impl::flush_database(
conn_mgr,
profile_name,
id,
*force,
output_format,
query,
)
.await
}
CloudDatabaseCommands::FlushCrdb { id, force } => {
super::database_impl::flush_crdb(
conn_mgr,
Expand All @@ -220,6 +231,16 @@ pub async fn handle_database_command(
)
.await
}
CloudDatabaseCommands::AvailableVersions { id } => {
super::database_impl::get_available_versions(
conn_mgr,
profile_name,
id,
output_format,
query,
)
.await
}
CloudDatabaseCommands::UpgradeStatus { id } => {
super::database_impl::get_upgrade_status(
conn_mgr,
Expand Down
113 changes: 113 additions & 0 deletions crates/redisctl/src/commands/cloud/database_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,119 @@ pub async fn delete_tag(
Ok(())
}

/// Flush standard (non-Active-Active) database
pub async fn flush_database(
conn_mgr: &ConnectionManager,
profile_name: Option<&str>,
id: &str,
force: bool,
output_format: OutputFormat,
query: Option<&str>,
) -> CliResult<()> {
let (subscription_id, database_id) = parse_database_id(id)?;

// Confirmation prompt unless --force is used
if !force {
use dialoguer::Confirm;
let confirm = Confirm::new()
.with_prompt(format!(
"Are you sure you want to flush database {}? This will delete all data!",
id
))
.default(false)
.interact()
.map_err(|e| RedisCtlError::InvalidInput {
message: format!("Failed to read confirmation: {}", e),
})?;

if !confirm {
println!("Flush operation cancelled");
return Ok(());
}
}

let client = conn_mgr.create_cloud_client(profile_name).await?;

let response = client
.put_raw(
&format!(
"/subscriptions/{}/databases/{}/flush",
subscription_id, database_id
),
json!({}),
)
.await
.context("Failed to flush database")?;

let result = if let Some(q) = query {
apply_jmespath(&response, q)?
} else {
response
};

match output_format {
OutputFormat::Table => {
println!("Database flush initiated");
if let Some(task_id) = result.get("taskId") {
println!("Task ID: {}", task_id);
}
}
_ => print_json_or_yaml(result, output_format)?,
}

Ok(())
}

/// Get available Redis versions for upgrade
pub async fn get_available_versions(
conn_mgr: &ConnectionManager,
profile_name: Option<&str>,
id: &str,
output_format: OutputFormat,
query: Option<&str>,
) -> CliResult<()> {
let (subscription_id, database_id) = parse_database_id(id)?;
let client = conn_mgr.create_cloud_client(profile_name).await?;

let response = client
.get_raw(&format!(
"/subscriptions/{}/databases/{}/available-target-versions",
subscription_id, database_id
))
.await
.context("Failed to get available versions")?;

let result = if let Some(q) = query {
apply_jmespath(&response, q)?
} else {
response
};

match output_format {
OutputFormat::Table => {
if let Some(versions) = result.as_array() {
if versions.is_empty() {
println!("No upgrade versions available");
} else {
println!("Available Redis versions for upgrade:");
for v in versions {
if let Some(version) = v.as_str() {
println!(" - {}", version);
} else {
println!(" - {}", v);
}
}
}
} else {
print_json_or_yaml(result, output_format)?;
}
}
_ => print_json_or_yaml(result, output_format)?,
}

Ok(())
}

/// Flush Active-Active database
pub async fn flush_crdb(
conn_mgr: &ConnectionManager,
Expand Down
Loading