From 5b460ef525368d3200eb7421b972cf0a4ea6c93f Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 12 May 2022 10:59:54 +0200 Subject: [PATCH] client: add --ns parameters to snapshot commands Signed-off-by: Wolfgang Bumiller --- proxmox-backup-client/src/mount.rs | 1 + proxmox-backup-client/src/snapshot.rs | 121 +++++++++++++++++--------- 2 files changed, 83 insertions(+), 39 deletions(-) diff --git a/proxmox-backup-client/src/mount.rs b/proxmox-backup-client/src/mount.rs index f26c9c7e..89130027 100644 --- a/proxmox-backup-client/src/mount.rs +++ b/proxmox-backup-client/src/mount.rs @@ -80,6 +80,7 @@ const API_METHOD_MAP: ApiMethod = ApiMethod::new( "Map a drive image from a VM backup to a local loopback device. Use 'unmap' to undo. WARNING: Only do this with *trusted* backups!", &sorted!([ + ("ns", true, &BackupNamespace::API_SCHEMA,), ( "snapshot", false, diff --git a/proxmox-backup-client/src/snapshot.rs b/proxmox-backup-client/src/snapshot.rs index fb287e37..ab50a824 100644 --- a/proxmox-backup-client/src/snapshot.rs +++ b/proxmox-backup-client/src/snapshot.rs @@ -20,6 +20,14 @@ use crate::{ optional_ns_param, record_repository, BackupDir, KEYFD_SCHEMA, KEYFILE_SCHEMA, REPO_URL_SCHEMA, }; +fn snapshot_args(ns: &BackupNamespace, snapshot: &BackupDir) -> Result { + let mut args = serde_json::to_value(snapshot)?; + if !ns.is_root() { + args["backup-ns"] = serde_json::to_value(ns)?; + } + Ok(args) +} + #[api( input: { properties: { @@ -27,7 +35,7 @@ use crate::{ schema: REPO_URL_SCHEMA, optional: true, }, - "ns": { + ns: { type: BackupNamespace, optional: true, }, @@ -103,6 +111,10 @@ async fn list_snapshots(param: Value) -> Result { schema: REPO_URL_SCHEMA, optional: true, }, + ns: { + type: BackupNamespace, + optional: true, + }, snapshot: { type: String, description: "Snapshot path.", @@ -118,6 +130,7 @@ async fn list_snapshots(param: Value) -> Result { async fn list_snapshot_files(param: Value) -> Result { let repo = extract_repository_from_value(¶m)?; + let backup_ns = optional_ns_param(¶m)?; let path = required_string_param(¶m, "snapshot")?; let snapshot: BackupDir = path.parse()?; @@ -128,7 +141,7 @@ async fn list_snapshot_files(param: Value) -> Result { let path = format!("api2/json/admin/datastore/{}/files", repo.store()); let mut result = client - .get(&path, Some(serde_json::to_value(snapshot)?)) + .get(&path, Some(snapshot_args(&backup_ns, &snapshot)?)) .await?; record_repository(&repo); @@ -145,23 +158,28 @@ async fn list_snapshot_files(param: Value) -> Result { } #[api( - input: { + input: { properties: { repository: { schema: REPO_URL_SCHEMA, optional: true, }, + ns: { + type: BackupNamespace, + optional: true, + }, snapshot: { type: String, description: "Snapshot path.", - }, + }, } - } + } )] /// Forget (remove) backup snapshots. async fn forget_snapshots(param: Value) -> Result { let repo = extract_repository_from_value(¶m)?; + let backup_ns = optional_ns_param(¶m)?; let path = required_string_param(¶m, "snapshot")?; let snapshot: BackupDir = path.parse()?; @@ -170,7 +188,7 @@ async fn forget_snapshots(param: Value) -> Result { let path = format!("api2/json/admin/datastore/{}/snapshots", repo.store()); let result = client - .delete(&path, Some(serde_json::to_value(snapshot)?)) + .delete(&path, Some(snapshot_args(&backup_ns, &snapshot)?)) .await?; record_repository(&repo); @@ -179,40 +197,45 @@ async fn forget_snapshots(param: Value) -> Result { } #[api( - input: { - properties: { - repository: { - schema: REPO_URL_SCHEMA, - optional: true, - }, - snapshot: { - type: String, - description: "Group/Snapshot path.", - }, - logfile: { - type: String, - description: "The path to the log file you want to upload.", - }, - keyfile: { - schema: KEYFILE_SCHEMA, - optional: true, - }, - "keyfd": { - schema: KEYFD_SCHEMA, - optional: true, - }, - "crypt-mode": { - type: CryptMode, - optional: true, - }, - } - } + input: { + properties: { + repository: { + schema: REPO_URL_SCHEMA, + optional: true, + }, + ns: { + type: BackupNamespace, + optional: true, + }, + snapshot: { + type: String, + description: "Group/Snapshot path.", + }, + logfile: { + type: String, + description: "The path to the log file you want to upload.", + }, + keyfile: { + schema: KEYFILE_SCHEMA, + optional: true, + }, + "keyfd": { + schema: KEYFD_SCHEMA, + optional: true, + }, + "crypt-mode": { + type: CryptMode, + optional: true, + }, + } + } )] /// Upload backup log file. async fn upload_log(param: Value) -> Result { let logfile = required_string_param(¶m, "logfile")?; let repo = extract_repository_from_value(¶m)?; + let backup_ns = optional_ns_param(¶m)?; let snapshot = required_string_param(¶m, "snapshot")?; let snapshot: BackupDir = snapshot.parse()?; @@ -246,7 +269,7 @@ async fn upload_log(param: Value) -> Result { repo.store() ); - let args = serde_json::to_value(&snapshot)?; + let args = snapshot_args(&backup_ns, &snapshot)?; let body = hyper::Body::from(raw_data); client @@ -261,6 +284,10 @@ async fn upload_log(param: Value) -> Result { schema: REPO_URL_SCHEMA, optional: true, }, + ns: { + type: BackupNamespace, + optional: true, + }, snapshot: { type: String, description: "Snapshot path.", @@ -277,12 +304,13 @@ async fn show_notes(param: Value) -> Result { let repo = extract_repository_from_value(¶m)?; let path = required_string_param(¶m, "snapshot")?; + let backup_ns = optional_ns_param(¶m)?; let snapshot: BackupDir = path.parse()?; let client = connect(&repo)?; let path = format!("api2/json/admin/datastore/{}/notes", repo.store()); - let args = serde_json::to_value(snapshot)?; + let args = snapshot_args(&backup_ns, &snapshot)?; let output_format = get_output_format(¶m); @@ -313,6 +341,10 @@ async fn show_notes(param: Value) -> Result { schema: REPO_URL_SCHEMA, optional: true, }, + ns: { + type: BackupNamespace, + optional: true, + }, snapshot: { type: String, description: "Snapshot path.", @@ -330,12 +362,13 @@ async fn update_notes(param: Value) -> Result { let path = required_string_param(¶m, "snapshot")?; let notes = required_string_param(¶m, "notes")?; + let backup_ns = optional_ns_param(¶m)?; let snapshot: BackupDir = path.parse()?; let client = connect(&repo)?; let path = format!("api2/json/admin/datastore/{}/notes", repo.store()); - let mut args = serde_json::to_value(snapshot)?; + let mut args = snapshot_args(&backup_ns, &snapshot)?; args["notes"] = Value::from(notes); client.put(&path, Some(args)).await?; @@ -350,6 +383,10 @@ async fn update_notes(param: Value) -> Result { schema: REPO_URL_SCHEMA, optional: true, }, + ns: { + type: BackupNamespace, + optional: true, + }, snapshot: { type: String, description: "Snapshot path.", @@ -366,12 +403,13 @@ async fn show_protection(param: Value) -> Result<(), Error> { let repo = extract_repository_from_value(¶m)?; let path = required_string_param(¶m, "snapshot")?; + let backup_ns = optional_ns_param(¶m)?; let snapshot: BackupDir = path.parse()?; let client = connect(&repo)?; let path = format!("api2/json/admin/datastore/{}/protected", repo.store()); - let args = serde_json::to_value(snapshot)?; + let args = snapshot_args(&backup_ns, &snapshot)?; let output_format = get_output_format(¶m); @@ -402,6 +440,10 @@ async fn show_protection(param: Value) -> Result<(), Error> { schema: REPO_URL_SCHEMA, optional: true, }, + ns: { + type: BackupNamespace, + optional: true, + }, snapshot: { type: String, description: "Snapshot path.", @@ -418,12 +460,13 @@ async fn update_protection(protected: bool, param: Value) -> Result<(), Error> { let repo = extract_repository_from_value(¶m)?; let path = required_string_param(¶m, "snapshot")?; + let backup_ns = optional_ns_param(¶m)?; let snapshot: BackupDir = path.parse()?; let client = connect(&repo)?; let path = format!("api2/json/admin/datastore/{}/protected", repo.store()); - let mut args = serde_json::to_value(snapshot)?; + let mut args = snapshot_args(&backup_ns, &snapshot)?; args["protected"] = Value::from(protected); client.put(&path, Some(args)).await?;