client: add --ns parameters to snapshot commands

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2022-05-12 10:59:54 +02:00
parent 03d4f43d5a
commit 5b460ef525
2 changed files with 83 additions and 39 deletions

View File

@ -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. "Map a drive image from a VM backup to a local loopback device. Use 'unmap' to undo.
WARNING: Only do this with *trusted* backups!", WARNING: Only do this with *trusted* backups!",
&sorted!([ &sorted!([
("ns", true, &BackupNamespace::API_SCHEMA,),
( (
"snapshot", "snapshot",
false, false,

View File

@ -20,6 +20,14 @@ use crate::{
optional_ns_param, record_repository, BackupDir, KEYFD_SCHEMA, KEYFILE_SCHEMA, REPO_URL_SCHEMA, optional_ns_param, record_repository, BackupDir, KEYFD_SCHEMA, KEYFILE_SCHEMA, REPO_URL_SCHEMA,
}; };
fn snapshot_args(ns: &BackupNamespace, snapshot: &BackupDir) -> Result<Value, Error> {
let mut args = serde_json::to_value(snapshot)?;
if !ns.is_root() {
args["backup-ns"] = serde_json::to_value(ns)?;
}
Ok(args)
}
#[api( #[api(
input: { input: {
properties: { properties: {
@ -27,7 +35,7 @@ use crate::{
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
"ns": { ns: {
type: BackupNamespace, type: BackupNamespace,
optional: true, optional: true,
}, },
@ -103,6 +111,10 @@ async fn list_snapshots(param: Value) -> Result<Value, Error> {
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
ns: {
type: BackupNamespace,
optional: true,
},
snapshot: { snapshot: {
type: String, type: String,
description: "Snapshot path.", description: "Snapshot path.",
@ -118,6 +130,7 @@ async fn list_snapshots(param: Value) -> Result<Value, Error> {
async fn list_snapshot_files(param: Value) -> Result<Value, Error> { async fn list_snapshot_files(param: Value) -> Result<Value, Error> {
let repo = extract_repository_from_value(&param)?; let repo = extract_repository_from_value(&param)?;
let backup_ns = optional_ns_param(&param)?;
let path = required_string_param(&param, "snapshot")?; let path = required_string_param(&param, "snapshot")?;
let snapshot: BackupDir = path.parse()?; let snapshot: BackupDir = path.parse()?;
@ -128,7 +141,7 @@ async fn list_snapshot_files(param: Value) -> Result<Value, Error> {
let path = format!("api2/json/admin/datastore/{}/files", repo.store()); let path = format!("api2/json/admin/datastore/{}/files", repo.store());
let mut result = client let mut result = client
.get(&path, Some(serde_json::to_value(snapshot)?)) .get(&path, Some(snapshot_args(&backup_ns, &snapshot)?))
.await?; .await?;
record_repository(&repo); record_repository(&repo);
@ -151,6 +164,10 @@ async fn list_snapshot_files(param: Value) -> Result<Value, Error> {
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
ns: {
type: BackupNamespace,
optional: true,
},
snapshot: { snapshot: {
type: String, type: String,
description: "Snapshot path.", description: "Snapshot path.",
@ -162,6 +179,7 @@ async fn list_snapshot_files(param: Value) -> Result<Value, Error> {
async fn forget_snapshots(param: Value) -> Result<Value, Error> { async fn forget_snapshots(param: Value) -> Result<Value, Error> {
let repo = extract_repository_from_value(&param)?; let repo = extract_repository_from_value(&param)?;
let backup_ns = optional_ns_param(&param)?;
let path = required_string_param(&param, "snapshot")?; let path = required_string_param(&param, "snapshot")?;
let snapshot: BackupDir = path.parse()?; let snapshot: BackupDir = path.parse()?;
@ -170,7 +188,7 @@ async fn forget_snapshots(param: Value) -> Result<Value, Error> {
let path = format!("api2/json/admin/datastore/{}/snapshots", repo.store()); let path = format!("api2/json/admin/datastore/{}/snapshots", repo.store());
let result = client let result = client
.delete(&path, Some(serde_json::to_value(snapshot)?)) .delete(&path, Some(snapshot_args(&backup_ns, &snapshot)?))
.await?; .await?;
record_repository(&repo); record_repository(&repo);
@ -185,6 +203,10 @@ async fn forget_snapshots(param: Value) -> Result<Value, Error> {
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
ns: {
type: BackupNamespace,
optional: true,
},
snapshot: { snapshot: {
type: String, type: String,
description: "Group/Snapshot path.", description: "Group/Snapshot path.",
@ -213,6 +235,7 @@ async fn upload_log(param: Value) -> Result<Value, Error> {
let logfile = required_string_param(&param, "logfile")?; let logfile = required_string_param(&param, "logfile")?;
let repo = extract_repository_from_value(&param)?; let repo = extract_repository_from_value(&param)?;
let backup_ns = optional_ns_param(&param)?;
let snapshot = required_string_param(&param, "snapshot")?; let snapshot = required_string_param(&param, "snapshot")?;
let snapshot: BackupDir = snapshot.parse()?; let snapshot: BackupDir = snapshot.parse()?;
@ -246,7 +269,7 @@ async fn upload_log(param: Value) -> Result<Value, Error> {
repo.store() repo.store()
); );
let args = serde_json::to_value(&snapshot)?; let args = snapshot_args(&backup_ns, &snapshot)?;
let body = hyper::Body::from(raw_data); let body = hyper::Body::from(raw_data);
client client
@ -261,6 +284,10 @@ async fn upload_log(param: Value) -> Result<Value, Error> {
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
ns: {
type: BackupNamespace,
optional: true,
},
snapshot: { snapshot: {
type: String, type: String,
description: "Snapshot path.", description: "Snapshot path.",
@ -277,12 +304,13 @@ async fn show_notes(param: Value) -> Result<Value, Error> {
let repo = extract_repository_from_value(&param)?; let repo = extract_repository_from_value(&param)?;
let path = required_string_param(&param, "snapshot")?; let path = required_string_param(&param, "snapshot")?;
let backup_ns = optional_ns_param(&param)?;
let snapshot: BackupDir = path.parse()?; let snapshot: BackupDir = path.parse()?;
let client = connect(&repo)?; let client = connect(&repo)?;
let path = format!("api2/json/admin/datastore/{}/notes", repo.store()); 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(&param); let output_format = get_output_format(&param);
@ -313,6 +341,10 @@ async fn show_notes(param: Value) -> Result<Value, Error> {
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
ns: {
type: BackupNamespace,
optional: true,
},
snapshot: { snapshot: {
type: String, type: String,
description: "Snapshot path.", description: "Snapshot path.",
@ -330,12 +362,13 @@ async fn update_notes(param: Value) -> Result<Value, Error> {
let path = required_string_param(&param, "snapshot")?; let path = required_string_param(&param, "snapshot")?;
let notes = required_string_param(&param, "notes")?; let notes = required_string_param(&param, "notes")?;
let backup_ns = optional_ns_param(&param)?;
let snapshot: BackupDir = path.parse()?; let snapshot: BackupDir = path.parse()?;
let client = connect(&repo)?; let client = connect(&repo)?;
let path = format!("api2/json/admin/datastore/{}/notes", repo.store()); 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); args["notes"] = Value::from(notes);
client.put(&path, Some(args)).await?; client.put(&path, Some(args)).await?;
@ -350,6 +383,10 @@ async fn update_notes(param: Value) -> Result<Value, Error> {
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
ns: {
type: BackupNamespace,
optional: true,
},
snapshot: { snapshot: {
type: String, type: String,
description: "Snapshot path.", description: "Snapshot path.",
@ -366,12 +403,13 @@ async fn show_protection(param: Value) -> Result<(), Error> {
let repo = extract_repository_from_value(&param)?; let repo = extract_repository_from_value(&param)?;
let path = required_string_param(&param, "snapshot")?; let path = required_string_param(&param, "snapshot")?;
let backup_ns = optional_ns_param(&param)?;
let snapshot: BackupDir = path.parse()?; let snapshot: BackupDir = path.parse()?;
let client = connect(&repo)?; let client = connect(&repo)?;
let path = format!("api2/json/admin/datastore/{}/protected", repo.store()); 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(&param); let output_format = get_output_format(&param);
@ -402,6 +440,10 @@ async fn show_protection(param: Value) -> Result<(), Error> {
schema: REPO_URL_SCHEMA, schema: REPO_URL_SCHEMA,
optional: true, optional: true,
}, },
ns: {
type: BackupNamespace,
optional: true,
},
snapshot: { snapshot: {
type: String, type: String,
description: "Snapshot path.", description: "Snapshot path.",
@ -418,12 +460,13 @@ async fn update_protection(protected: bool, param: Value) -> Result<(), Error> {
let repo = extract_repository_from_value(&param)?; let repo = extract_repository_from_value(&param)?;
let path = required_string_param(&param, "snapshot")?; let path = required_string_param(&param, "snapshot")?;
let backup_ns = optional_ns_param(&param)?;
let snapshot: BackupDir = path.parse()?; let snapshot: BackupDir = path.parse()?;
let client = connect(&repo)?; let client = connect(&repo)?;
let path = format!("api2/json/admin/datastore/{}/protected", repo.store()); 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); args["protected"] = Value::from(protected);
client.put(&path, Some(args)).await?; client.put(&path, Some(args)).await?;