Skip to content

Commit

Permalink
Implement the instance backup command for Cloud instances (#1379)
Browse files Browse the repository at this point in the history
* Implement the `instance backup` command for Cloud instances

* cargo fmt
  • Loading branch information
elprans authored Oct 11, 2024
1 parent 7e8dd93 commit 593c100
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 1 deletion.
27 changes: 27 additions & 0 deletions src/cloud/backups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ pub struct Backup {
pub edgedb_version: String,
}

#[derive(Debug, serde::Serialize)]
pub struct CloudInstanceBackup {
pub name: String,
pub org: String,
}

#[derive(Debug, serde::Serialize)]
pub struct CloudInstanceRestore {
pub name: String,
Expand All @@ -24,6 +30,27 @@ pub struct CloudInstanceRestore {
pub source_instance_id: Option<String>,
}

#[tokio::main(flavor = "current_thread")]
pub async fn backup_cloud_instance(
client: &CloudClient,
request: &CloudInstanceBackup,
) -> anyhow::Result<()> {
let url = format!("orgs/{}/instances/{}/backups", request.org, request.name);
let operation: CloudOperation = client.post(url, request).await.or_else(|e| match e
.downcast_ref::<ErrorResponse>(
) {
Some(ErrorResponse {
code: reqwest::StatusCode::NOT_FOUND,
..
}) => {
anyhow::bail!("specified instance could not be found",);
}
_ => Err(e),
})?;
wait_for_operation(operation, client).await?;
Ok(())
}

#[tokio::main(flavor = "current_thread")]
pub async fn restore_cloud_instance(
client: &CloudClient,
Expand Down
51 changes: 50 additions & 1 deletion src/portable/backup.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use color_print::cformat;

use crate::cloud;
use crate::portable::options::{InstanceName, ListBackups, Restore};
use crate::portable::options::{Backup, InstanceName, ListBackups, Restore};
use crate::print::echo;
use crate::question;

Expand Down Expand Up @@ -32,6 +32,55 @@ fn list_cloud_backups_cmd(
Ok(())
}

pub fn backup(cmd: &Backup, opts: &crate::options::Options) -> anyhow::Result<()> {
match &cmd.instance {
InstanceName::Local(_) => Err(opts.error(
clap::error::ErrorKind::InvalidValue,
cformat!("Only Cloud instances can be backed up using this command."),
))?,
InstanceName::Cloud {
org_slug: org,
name,
} => backup_cloud_cmd(cmd, org, name, opts),
}
}

fn backup_cloud_cmd(
cmd: &Backup,
org_slug: &str,
name: &str,
opts: &crate::options::Options,
) -> anyhow::Result<()> {
let client = cloud::client::CloudClient::new(&opts.cloud_options)?;
client.ensure_authenticated()?;

let inst_name = InstanceName::Cloud {
org_slug: org_slug.to_string(),
name: name.to_string(),
};

let prompt = format!(
"Will create a backup for the \"{inst_name}\" Cloud instance:\
\n\nContinue?",
);

if !cmd.non_interactive && !question::Confirm::new(prompt).ask()? {
return Ok(());
}

let request = cloud::backups::CloudInstanceBackup {
name: name.to_string(),
org: org_slug.to_string(),
};
cloud::backups::backup_cloud_instance(&client, &request)?;

echo!(
"Successfully created a backup for EdgeDB Cloud instance",
inst_name,
);
Ok(())
}

pub fn restore(cmd: &Restore, opts: &crate::options::Options) -> anyhow::Result<()> {
match &cmd.instance {
InstanceName::Local(_) => Err(opts.error(
Expand Down
1 change: 1 addition & 0 deletions src/portable/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub fn instance_main(cmd: &ServerInstanceCommand, options: &Options) -> Result<(
List(c) if cfg!(windows) => windows::list(c, options),
List(c) => status::list(c, options),
Resize(c) => resize::resize(c, options),
Backup(c) => backup::backup(c, options),
Restore(c) => backup::restore(c, options),
ListBackups(c) => backup::list(c, options),
Upgrade(c) => upgrade::upgrade(c, options),
Expand Down
17 changes: 17 additions & 0 deletions src/portable/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub enum InstanceCommand {
Logs(Logs),
/// Resize a Cloud instance.
Resize(Resize),
/// Create a Cloud instance backup.
Backup(Backup),
/// Restore a Cloud instance from a backup.
Restore(Restore),
/// Restore a Cloud instance from a backup.
Expand Down Expand Up @@ -537,6 +539,21 @@ pub struct ListBackups {
pub json: bool,
}

#[derive(clap::Args, IntoArgs, Debug, Clone)]
pub struct Backup {
#[command(flatten)]
pub cloud_opts: CloudOptions,

/// Instance to restore.
#[arg(short = 'I', long, required = true)]
#[arg(value_hint=ValueHint::Other)] // TODO complete instance name
pub instance: InstanceName,

/// Do not ask questions.
#[arg(long)]
pub non_interactive: bool,
}

#[derive(clap::Args, IntoArgs, Clone, Debug)]
#[group(id = "backupspec", required = true)]
pub struct BackupSpec {
Expand Down

0 comments on commit 593c100

Please sign in to comment.