From 709538df7f8b1322a20765ceccab35e9c632dc03 Mon Sep 17 00:00:00 2001 From: Josh Priddle Date: Fri, 20 Feb 2026 12:25:13 -0500 Subject: [PATCH 1/3] Add backup command --- src/cli.rs | 35 +++++++++ src/commands/backup.rs | 172 +++++++++++++++++++++++++++++++++++++++++ src/commands/mod.rs | 1 + src/main.rs | 33 ++++++-- tests/cli.rs | 49 ++++++++++++ 5 files changed, 284 insertions(+), 6 deletions(-) create mode 100644 src/commands/backup.rs diff --git a/src/cli.rs b/src/cli.rs index 4b71f16..a731155 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -70,6 +70,11 @@ pub enum Commands { #[command(subcommand)] command: WebhookCommands, }, + /// Manage backups + Backup { + #[command(subcommand)] + command: BackupCommands, + }, /// List available PHP versions PhpVersions, /// Configure MCP integration for Claude @@ -955,6 +960,36 @@ pub enum EventCommands { }, } +#[derive(Subcommand)] +pub enum BackupCommands { + /// List backups for a site + List { + /// Site ID + site_id: String, + /// Page number + #[arg(long, default_value = "1")] + page: u32, + /// Items per page + #[arg(long, default_value = "15")] + per_page: u32, + }, + /// Show backup details + Show { + /// Site ID + site_id: String, + /// Backup ID + backup_id: String, + }, + /// Create a manual backup + Create { + /// Site ID + site_id: String, + /// Backup description + #[arg(long)] + description: Option, + }, +} + #[derive(Subcommand)] pub enum WebhookCommands { /// List webhooks diff --git a/src/commands/backup.rs b/src/commands/backup.rs new file mode 100644 index 0000000..01c745b --- /dev/null +++ b/src/commands/backup.rs @@ -0,0 +1,172 @@ +use serde::Serialize; +use serde_json::Value; + +use crate::api::{ApiClient, ApiError}; +use crate::output::{ + OutputFormat, extract_pagination, format_option, print_json, print_key_value, print_message, + print_pagination, print_table, +}; + +#[derive(Debug, Serialize)] +struct PaginationQuery { + page: u32, + per_page: u32, +} + +#[derive(Debug, Serialize)] +struct CreateBackupRequest { + r#type: String, + #[serde(skip_serializing_if = "Option::is_none")] + description: Option, +} + +pub fn list( + client: &ApiClient, + site_id: &str, + page: u32, + per_page: u32, + format: OutputFormat, +) -> Result<(), ApiError> { + let query = PaginationQuery { page, per_page }; + let response: Value = client.get_with_query( + &format!("/api/v1/vector/sites/{}/backups", site_id), + &query, + )?; + + if format == OutputFormat::Json { + print_json(&response); + return Ok(()); + } + + let backups = response["data"] + .as_array() + .ok_or_else(|| ApiError::Other("Invalid response format".to_string()))?; + + if backups.is_empty() { + print_message("No backups found."); + return Ok(()); + } + + let rows: Vec> = backups + .iter() + .map(|b| { + vec![ + b["id"].as_str().unwrap_or("-").to_string(), + b["type"].as_str().unwrap_or("-").to_string(), + b["status"].as_str().unwrap_or("-").to_string(), + format_option(&b["description"].as_str().map(String::from)), + format_option(&b["created_at"].as_str().map(String::from)), + ] + }) + .collect(); + + print_table(vec!["ID", "Type", "Status", "Description", "Created"], rows); + + if let Some((current, last, total)) = extract_pagination(&response) { + print_pagination(current, last, total); + } + + Ok(()) +} + +pub fn show( + client: &ApiClient, + site_id: &str, + backup_id: &str, + format: OutputFormat, +) -> Result<(), ApiError> { + let response: Value = client.get(&format!( + "/api/v1/vector/sites/{}/backups/{}", + site_id, backup_id + ))?; + + if format == OutputFormat::Json { + print_json(&response); + return Ok(()); + } + + let backup = &response["data"]; + + print_key_value(vec![ + ("ID", backup["id"].as_str().unwrap_or("-").to_string()), + ("Type", backup["type"].as_str().unwrap_or("-").to_string()), + ( + "Status", + backup["status"].as_str().unwrap_or("-").to_string(), + ), + ( + "Description", + format_option(&backup["description"].as_str().map(String::from)), + ), + ( + "Snapshot ID", + format_option(&backup["snapshot_id"].as_str().map(String::from)), + ), + ( + "Started At", + format_option(&backup["started_at"].as_str().map(String::from)), + ), + ( + "Completed At", + format_option(&backup["completed_at"].as_str().map(String::from)), + ), + ( + "Created At", + format_option(&backup["created_at"].as_str().map(String::from)), + ), + ( + "Updated At", + format_option(&backup["updated_at"].as_str().map(String::from)), + ), + ]); + + Ok(()) +} + +pub fn create( + client: &ApiClient, + site_id: &str, + description: Option, + format: OutputFormat, +) -> Result<(), ApiError> { + let body = CreateBackupRequest { + r#type: "manual".to_string(), + description, + }; + + let response: Value = client.post( + &format!("/api/v1/vector/sites/{}/backups", site_id), + &body, + )?; + + if format == OutputFormat::Json { + print_json(&response); + return Ok(()); + } + + let backup = &response["data"]; + print_message(&format!( + "Backup created: {} ({})", + backup["id"].as_str().unwrap_or("-"), + backup["status"].as_str().unwrap_or("-") + )); + + print_key_value(vec![ + ("ID", backup["id"].as_str().unwrap_or("-").to_string()), + ("Type", backup["type"].as_str().unwrap_or("-").to_string()), + ( + "Status", + backup["status"].as_str().unwrap_or("-").to_string(), + ), + ( + "Description", + format_option(&backup["description"].as_str().map(String::from)), + ), + ( + "Created At", + format_option(&backup["created_at"].as_str().map(String::from)), + ), + ]); + + Ok(()) +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index bc3ee48..7ba25b1 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,5 +1,6 @@ pub mod account; pub mod auth; +pub mod backup; pub mod db; pub mod deploy; pub mod env; diff --git a/src/main.rs b/src/main.rs index ecc4182..abf8fd2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,13 +11,13 @@ use std::process; use api::{ApiClient, ApiError, EXIT_SUCCESS}; use cli::{ AccountApiKeyCommands, AccountCommands, AccountSecretCommands, AccountSshKeyCommands, - AuthCommands, Cli, Commands, DbCommands, DbExportCommands, DbImportSessionCommands, - DeployCommands, EnvCommands, EnvDbCommands, EnvDbImportSessionCommands, EnvSecretCommands, - EventCommands, McpCommands, SiteCommands, SiteSshKeyCommands, SslCommands, - WafAllowedReferrerCommands, WafBlockedIpCommands, WafBlockedReferrerCommands, WafCommands, - WafRateLimitCommands, WebhookCommands, + AuthCommands, BackupCommands, Cli, Commands, DbCommands, DbExportCommands, + DbImportSessionCommands, DeployCommands, EnvCommands, EnvDbCommands, + EnvDbImportSessionCommands, EnvSecretCommands, EventCommands, McpCommands, SiteCommands, + SiteSshKeyCommands, SslCommands, WafAllowedReferrerCommands, WafBlockedIpCommands, + WafBlockedReferrerCommands, WafCommands, WafRateLimitCommands, WebhookCommands, }; -use commands::{account, auth, db, deploy, env, event, mcp, site, ssl, waf, webhook}; +use commands::{account, auth, backup, db, deploy, env, event, mcp, site, ssl, waf, webhook}; use config::{Config, Credentials}; use output::{OutputFormat, print_error, print_json, print_message, print_table}; @@ -46,6 +46,7 @@ fn run(command: Commands, format: OutputFormat) -> Result<(), ApiError> { Commands::Db { command } => run_db(command, format), Commands::Waf { command } => run_waf(command, format), Commands::Account { command } => run_account(command, format), + Commands::Backup { command } => run_backup(command, format), Commands::Event { command } => run_event(command, format), Commands::Webhook { command } => run_webhook(command, format), Commands::PhpVersions => run_php_versions(format), @@ -612,6 +613,26 @@ fn run_account_secret( } } +fn run_backup(command: BackupCommands, format: OutputFormat) -> Result<(), ApiError> { + let client = get_client()?; + + match command { + BackupCommands::List { + site_id, + page, + per_page, + } => backup::list(&client, &site_id, page, per_page, format), + BackupCommands::Show { + site_id, + backup_id, + } => backup::show(&client, &site_id, &backup_id, format), + BackupCommands::Create { + site_id, + description, + } => backup::create(&client, &site_id, description, format), + } +} + fn run_event(command: EventCommands, format: OutputFormat) -> Result<(), ApiError> { let client = get_client()?; diff --git a/tests/cli.rs b/tests/cli.rs index 503dccf..c265b45 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -164,6 +164,55 @@ fn test_site_list_requires_auth() { assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR } +#[test] +fn test_backup_help() { + let output = vector_cmd() + .args(["backup", "--help"]) + .output() + .expect("Failed to run"); + assert!(output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(stdout.contains("list")); + assert!(stdout.contains("show")); + assert!(stdout.contains("create")); +} + +#[test] +fn test_backup_list_requires_auth() { + let output = vector_cmd() + .args(["backup", "list", "test-site"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR +} + +#[test] +fn test_backup_show_requires_auth() { + let output = vector_cmd() + .args(["backup", "show", "test-site", "test-backup"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR +} + +#[test] +fn test_backup_create_requires_auth() { + let output = vector_cmd() + .args(["backup", "create", "test-site"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR +} + #[test] fn test_invalid_subcommand() { let output = vector_cmd() From 121b64d02dd034635a800d1e3dfe724cabd1d98b Mon Sep 17 00:00:00 2001 From: Josh Priddle Date: Tue, 24 Feb 2026 12:44:14 -0500 Subject: [PATCH 2/3] Add restore command --- src/cli.rs | 37 ++++++++ src/commands/mod.rs | 1 + src/commands/restore.rs | 187 ++++++++++++++++++++++++++++++++++++++++ src/main.rs | 31 ++++++- tests/cli.rs | 99 +++++++++++++++++++++ 5 files changed, 351 insertions(+), 4 deletions(-) create mode 100644 src/commands/restore.rs diff --git a/src/cli.rs b/src/cli.rs index a731155..68a2c71 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -75,6 +75,11 @@ pub enum Commands { #[command(subcommand)] command: BackupCommands, }, + /// Manage restores + Restore { + #[command(subcommand)] + command: RestoreCommands, + }, /// List available PHP versions PhpVersions, /// Configure MCP integration for Claude @@ -990,6 +995,38 @@ pub enum BackupCommands { }, } +#[derive(Subcommand)] +pub enum RestoreCommands { + /// List restores for a site + List { + /// Site ID + site_id: String, + /// Page number + #[arg(long, default_value = "1")] + page: u32, + /// Items per page + #[arg(long, default_value = "15")] + per_page: u32, + }, + /// Show restore details + Show { + /// Site ID + site_id: String, + /// Restore ID + restore_id: String, + }, + /// Create a restore from a backup + Create { + /// Site ID + site_id: String, + /// Backup ID to restore from + backup_id: String, + /// Restore scope (full, database, files) + #[arg(long, default_value = "full")] + scope: String, + }, +} + #[derive(Subcommand)] pub enum WebhookCommands { /// List webhooks diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 7ba25b1..2286ba1 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -2,6 +2,7 @@ pub mod account; pub mod auth; pub mod backup; pub mod db; +pub mod restore; pub mod deploy; pub mod env; pub mod event; diff --git a/src/commands/restore.rs b/src/commands/restore.rs new file mode 100644 index 0000000..0917fb1 --- /dev/null +++ b/src/commands/restore.rs @@ -0,0 +1,187 @@ +use serde::Serialize; +use serde_json::Value; + +use crate::api::{ApiClient, ApiError}; +use crate::output::{ + OutputFormat, extract_pagination, format_option, print_json, print_key_value, print_message, + print_pagination, print_table, +}; + +#[derive(Debug, Serialize)] +struct PaginationQuery { + page: u32, + per_page: u32, +} + +#[derive(Debug, Serialize)] +struct CreateRestoreRequest { + backup_id: String, + scope: String, +} + +pub fn list( + client: &ApiClient, + site_id: &str, + page: u32, + per_page: u32, + format: OutputFormat, +) -> Result<(), ApiError> { + let query = PaginationQuery { page, per_page }; + let response: Value = client.get_with_query( + &format!("/api/v1/vector/sites/{}/restores", site_id), + &query, + )?; + + if format == OutputFormat::Json { + print_json(&response); + return Ok(()); + } + + let restores = response["data"] + .as_array() + .ok_or_else(|| ApiError::Other("Invalid response format".to_string()))?; + + if restores.is_empty() { + print_message("No restores found."); + return Ok(()); + } + + let rows: Vec> = restores + .iter() + .map(|r| { + vec![ + r["id"].as_str().unwrap_or("-").to_string(), + r["vector_backup_id"].as_str().unwrap_or("-").to_string(), + r["scope"].as_str().unwrap_or("-").to_string(), + r["status"].as_str().unwrap_or("-").to_string(), + format_option(&r["created_at"].as_str().map(String::from)), + ] + }) + .collect(); + + print_table(vec!["ID", "Backup ID", "Scope", "Status", "Created"], rows); + + if let Some((current, last, total)) = extract_pagination(&response) { + print_pagination(current, last, total); + } + + Ok(()) +} + +pub fn show( + client: &ApiClient, + site_id: &str, + restore_id: &str, + format: OutputFormat, +) -> Result<(), ApiError> { + let response: Value = client.get(&format!( + "/api/v1/vector/sites/{}/restores/{}", + site_id, restore_id + ))?; + + if format == OutputFormat::Json { + print_json(&response); + return Ok(()); + } + + let restore = &response["data"]; + + print_key_value(vec![ + ("ID", restore["id"].as_str().unwrap_or("-").to_string()), + ( + "Backup ID", + restore["vector_backup_id"].as_str().unwrap_or("-").to_string(), + ), + ( + "Scope", + restore["scope"].as_str().unwrap_or("-").to_string(), + ), + ( + "Trigger", + restore["trigger"].as_str().unwrap_or("-").to_string(), + ), + ( + "Status", + restore["status"].as_str().unwrap_or("-").to_string(), + ), + ( + "Error Message", + format_option(&restore["error_message"].as_str().map(String::from)), + ), + ( + "Duration (ms)", + format_option(&restore["duration_ms"].as_u64().map(|d| d.to_string())), + ), + ( + "Started At", + format_option(&restore["started_at"].as_str().map(String::from)), + ), + ( + "Completed At", + format_option(&restore["completed_at"].as_str().map(String::from)), + ), + ( + "Created At", + format_option(&restore["created_at"].as_str().map(String::from)), + ), + ( + "Updated At", + format_option(&restore["updated_at"].as_str().map(String::from)), + ), + ]); + + Ok(()) +} + +pub fn create( + client: &ApiClient, + site_id: &str, + backup_id: &str, + scope: &str, + format: OutputFormat, +) -> Result<(), ApiError> { + let body = CreateRestoreRequest { + backup_id: backup_id.to_string(), + scope: scope.to_string(), + }; + + let response: Value = client.post( + &format!("/api/v1/vector/sites/{}/restores", site_id), + &body, + )?; + + if format == OutputFormat::Json { + print_json(&response); + return Ok(()); + } + + let restore = &response["data"]; + let restore_id = restore["id"].as_str().unwrap_or("-"); + + print_message(&format!( + "Restore initiated. Use `vector restore show {} {}` to check progress.", + site_id, restore_id + )); + + print_key_value(vec![ + ("ID", restore_id.to_string()), + ( + "Backup ID", + restore["vector_backup_id"].as_str().unwrap_or("-").to_string(), + ), + ( + "Scope", + restore["scope"].as_str().unwrap_or("-").to_string(), + ), + ( + "Status", + restore["status"].as_str().unwrap_or("-").to_string(), + ), + ( + "Created At", + format_option(&restore["created_at"].as_str().map(String::from)), + ), + ]); + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index abf8fd2..75c1995 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,11 +13,12 @@ use cli::{ AccountApiKeyCommands, AccountCommands, AccountSecretCommands, AccountSshKeyCommands, AuthCommands, BackupCommands, Cli, Commands, DbCommands, DbExportCommands, DbImportSessionCommands, DeployCommands, EnvCommands, EnvDbCommands, - EnvDbImportSessionCommands, EnvSecretCommands, EventCommands, McpCommands, SiteCommands, - SiteSshKeyCommands, SslCommands, WafAllowedReferrerCommands, WafBlockedIpCommands, - WafBlockedReferrerCommands, WafCommands, WafRateLimitCommands, WebhookCommands, + EnvDbImportSessionCommands, EnvSecretCommands, EventCommands, McpCommands, RestoreCommands, + SiteCommands, SiteSshKeyCommands, SslCommands, WafAllowedReferrerCommands, + WafBlockedIpCommands, WafBlockedReferrerCommands, WafCommands, WafRateLimitCommands, + WebhookCommands, }; -use commands::{account, auth, backup, db, deploy, env, event, mcp, site, ssl, waf, webhook}; +use commands::{account, auth, backup, db, deploy, env, event, mcp, restore, site, ssl, waf, webhook}; use config::{Config, Credentials}; use output::{OutputFormat, print_error, print_json, print_message, print_table}; @@ -47,6 +48,7 @@ fn run(command: Commands, format: OutputFormat) -> Result<(), ApiError> { Commands::Waf { command } => run_waf(command, format), Commands::Account { command } => run_account(command, format), Commands::Backup { command } => run_backup(command, format), + Commands::Restore { command } => run_restore(command, format), Commands::Event { command } => run_event(command, format), Commands::Webhook { command } => run_webhook(command, format), Commands::PhpVersions => run_php_versions(format), @@ -633,6 +635,27 @@ fn run_backup(command: BackupCommands, format: OutputFormat) -> Result<(), ApiEr } } +fn run_restore(command: RestoreCommands, format: OutputFormat) -> Result<(), ApiError> { + let client = get_client()?; + + match command { + RestoreCommands::List { + site_id, + page, + per_page, + } => restore::list(&client, &site_id, page, per_page, format), + RestoreCommands::Show { + site_id, + restore_id, + } => restore::show(&client, &site_id, &restore_id, format), + RestoreCommands::Create { + site_id, + backup_id, + scope, + } => restore::create(&client, &site_id, &backup_id, &scope, format), + } +} + fn run_event(command: EventCommands, format: OutputFormat) -> Result<(), ApiError> { let client = get_client()?; diff --git a/tests/cli.rs b/tests/cli.rs index c265b45..49a8031 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -23,6 +23,7 @@ fn test_help() { assert!(stdout.contains("deploy")); assert!(stdout.contains("ssl")); assert!(stdout.contains("mcp")); + assert!(stdout.contains("restore")); } #[test] @@ -213,6 +214,104 @@ fn test_backup_create_requires_auth() { assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR } +#[test] +fn test_restore_list_requires_auth() { + let output = vector_cmd() + .args(["restore", "list", "test-site"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR +} + +#[test] +fn test_restore_show_requires_auth() { + let output = vector_cmd() + .args(["restore", "show", "test-site", "test-restore"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR +} + +#[test] +fn test_restore_create_requires_auth() { + let output = vector_cmd() + .args(["restore", "create", "test-site", "test-backup"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); // EXIT_AUTH_ERROR +} + +#[test] +fn test_restore_help() { + let output = vector_cmd() + .args(["restore", "--help"]) + .output() + .expect("Failed to run"); + assert!(output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(stdout.contains("list")); + assert!(stdout.contains("show")); + assert!(stdout.contains("create")); +} + +#[test] +fn test_restore_create_help() { + let output = vector_cmd() + .args(["restore", "create", "--help"]) + .output() + .expect("Failed to run"); + assert!(output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(stdout.contains("--scope")); + assert!(stdout.contains("full, database, files")); + assert!(stdout.contains("[default: full]")); +} + +#[test] +fn test_restore_create_scope_default_requires_auth() { + let output = vector_cmd() + .args(["restore", "create", "test-site", "test-backup"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn test_restore_create_scope_database_requires_auth() { + let output = vector_cmd() + .args(["restore", "create", "test-site", "test-backup", "--scope", "database"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn test_restore_create_scope_files_requires_auth() { + let output = vector_cmd() + .args(["restore", "create", "test-site", "test-backup", "--scope", "files"]) + .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) + .env_remove("VECTOR_API_KEY") + .output() + .expect("Failed to run"); + assert!(!output.status.success()); + assert_eq!(output.status.code(), Some(2)); +} + #[test] fn test_invalid_subcommand() { let output = vector_cmd() From ee12ea82f2d5ecdca39a0b7b8a5b412693161efc Mon Sep 17 00:00:00 2001 From: Josh Priddle Date: Wed, 25 Feb 2026 12:36:08 -0500 Subject: [PATCH 3/3] Appease linter --- src/commands/backup.rs | 12 ++++-------- src/commands/mod.rs | 2 +- src/commands/restore.rs | 16 ++++++++++------ src/main.rs | 11 ++++++----- tests/cli.rs | 18 ++++++++++++++++-- 5 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/commands/backup.rs b/src/commands/backup.rs index 01c745b..0d4dbc9 100644 --- a/src/commands/backup.rs +++ b/src/commands/backup.rs @@ -28,10 +28,8 @@ pub fn list( format: OutputFormat, ) -> Result<(), ApiError> { let query = PaginationQuery { page, per_page }; - let response: Value = client.get_with_query( - &format!("/api/v1/vector/sites/{}/backups", site_id), - &query, - )?; + let response: Value = + client.get_with_query(&format!("/api/v1/vector/sites/{}/backups", site_id), &query)?; if format == OutputFormat::Json { print_json(&response); @@ -134,10 +132,8 @@ pub fn create( description, }; - let response: Value = client.post( - &format!("/api/v1/vector/sites/{}/backups", site_id), - &body, - )?; + let response: Value = + client.post(&format!("/api/v1/vector/sites/{}/backups", site_id), &body)?; if format == OutputFormat::Json { print_json(&response); diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 2286ba1..1e06179 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -2,11 +2,11 @@ pub mod account; pub mod auth; pub mod backup; pub mod db; -pub mod restore; pub mod deploy; pub mod env; pub mod event; pub mod mcp; +pub mod restore; pub mod site; pub mod ssl; pub mod waf; diff --git a/src/commands/restore.rs b/src/commands/restore.rs index 0917fb1..4e86f0c 100644 --- a/src/commands/restore.rs +++ b/src/commands/restore.rs @@ -90,7 +90,10 @@ pub fn show( ("ID", restore["id"].as_str().unwrap_or("-").to_string()), ( "Backup ID", - restore["vector_backup_id"].as_str().unwrap_or("-").to_string(), + restore["vector_backup_id"] + .as_str() + .unwrap_or("-") + .to_string(), ), ( "Scope", @@ -145,10 +148,8 @@ pub fn create( scope: scope.to_string(), }; - let response: Value = client.post( - &format!("/api/v1/vector/sites/{}/restores", site_id), - &body, - )?; + let response: Value = + client.post(&format!("/api/v1/vector/sites/{}/restores", site_id), &body)?; if format == OutputFormat::Json { print_json(&response); @@ -167,7 +168,10 @@ pub fn create( ("ID", restore_id.to_string()), ( "Backup ID", - restore["vector_backup_id"].as_str().unwrap_or("-").to_string(), + restore["vector_backup_id"] + .as_str() + .unwrap_or("-") + .to_string(), ), ( "Scope", diff --git a/src/main.rs b/src/main.rs index 75c1995..0776207 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,9 @@ use cli::{ WafBlockedIpCommands, WafBlockedReferrerCommands, WafCommands, WafRateLimitCommands, WebhookCommands, }; -use commands::{account, auth, backup, db, deploy, env, event, mcp, restore, site, ssl, waf, webhook}; +use commands::{ + account, auth, backup, db, deploy, env, event, mcp, restore, site, ssl, waf, webhook, +}; use config::{Config, Credentials}; use output::{OutputFormat, print_error, print_json, print_message, print_table}; @@ -624,10 +626,9 @@ fn run_backup(command: BackupCommands, format: OutputFormat) -> Result<(), ApiEr page, per_page, } => backup::list(&client, &site_id, page, per_page, format), - BackupCommands::Show { - site_id, - backup_id, - } => backup::show(&client, &site_id, &backup_id, format), + BackupCommands::Show { site_id, backup_id } => { + backup::show(&client, &site_id, &backup_id, format) + } BackupCommands::Create { site_id, description, diff --git a/tests/cli.rs b/tests/cli.rs index 49a8031..4e5fe83 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -291,7 +291,14 @@ fn test_restore_create_scope_default_requires_auth() { #[test] fn test_restore_create_scope_database_requires_auth() { let output = vector_cmd() - .args(["restore", "create", "test-site", "test-backup", "--scope", "database"]) + .args([ + "restore", + "create", + "test-site", + "test-backup", + "--scope", + "database", + ]) .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) .env_remove("VECTOR_API_KEY") .output() @@ -303,7 +310,14 @@ fn test_restore_create_scope_database_requires_auth() { #[test] fn test_restore_create_scope_files_requires_auth() { let output = vector_cmd() - .args(["restore", "create", "test-site", "test-backup", "--scope", "files"]) + .args([ + "restore", + "create", + "test-site", + "test-backup", + "--scope", + "files", + ]) .env("VECTOR_CONFIG_DIR", &nonexistent_config_dir()) .env_remove("VECTOR_API_KEY") .output()