From 141304d64ebcf40242acf4a4888fcc2e8b038707 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 10 Jan 2020 13:28:15 +0100 Subject: [PATCH] src/api2/config/remotes.rs: new API to configure remotes --- src/api2/config.rs | 4 +- src/api2/config/remotes.rs | 108 +++++++++++++++++++++++++++++++++++++ src/config/remotes.rs | 14 ++--- 3 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 src/api2/config/remotes.rs diff --git a/src/api2/config.rs b/src/api2/config.rs index e782d68c..749a9ac3 100644 --- a/src/api2/config.rs +++ b/src/api2/config.rs @@ -2,9 +2,11 @@ use proxmox::api::router::{Router, SubdirMap}; use proxmox::api::list_subdirs_api_method; pub mod datastore; +pub mod remotes; const SUBDIRS: SubdirMap = &[ - ("datastore", &datastore::ROUTER) + ("datastore", &datastore::ROUTER), + ("remotes", &remotes::ROUTER), ]; pub const ROUTER: Router = Router::new() diff --git a/src/api2/config/remotes.rs b/src/api2/config/remotes.rs new file mode 100644 index 00000000..6fb3725b --- /dev/null +++ b/src/api2/config/remotes.rs @@ -0,0 +1,108 @@ +use std::path::PathBuf; + +use failure::*; +use serde_json::Value; + +use proxmox::api::{api, ApiHandler, ApiMethod, Router, RpcEnvironment}; +use proxmox::api::schema::*; + +use crate::api2::types::*; +use crate::backup::*; +use crate::config::remotes; +use crate::tools; + +#[api( + input: { + properties: {}, + }, + returns: { + description: "The list of configured remotes.", + type: Array, + items: { + type: remotes::Remote, + }, + }, +)] +/// List all remotes +pub fn list_remotes( + _param: Value, + _info: &ApiMethod, + _rpcenv: &mut dyn RpcEnvironment, +) -> Result { + + let config = remotes::config()?; + + Ok(config.convert_to_array("name")) +} + +#[api( + input: { + properties: { + name: { + schema: remotes::REMOTE_ID_SCHEMA, + }, + comment: { + optional: true, + schema: remotes::COMMENT_SCHEMA, + }, + host: { + schema: remotes::REMOTE_HOST_SCHEMA, + }, + userid: { + schema: remotes::REMOTE_USERID_SCHEMA, + }, + password: { + schema: remotes::REMOTE_PASSWORD_SCHEMA, + }, + }, + }, +)] +/// Create new remote. +pub fn create_remote(name: String, param: Value) -> Result<(), Error> { + + // fixme: locking ? + + let remote: remotes::Remote = serde_json::from_value(param.clone())?; + + let mut config = remotes::config()?; + + if let Some(_) = config.sections.get(&name) { + bail!("remote '{}' already exists.", name); + } + + config.set_data(&name, "remote", serde_json::to_value(&remote)?); + + remotes::save_config(&config)?; + + Ok(()) +} + +#[api( + input: { + properties: { + name: { + schema: remotes::REMOTE_ID_SCHEMA, + }, + }, + }, +)] +/// Remove a remote from the configuration file. +pub fn delete_remote(name: String) -> Result<(), Error> { + + // fixme: locking ? + // fixme: check digest ? + + let mut config = remotes::config()?; + + match config.sections.get(&name) { + Some(_) => { config.sections.remove(&name); }, + None => bail!("remote '{}' does not exist.", name), + } + + Ok(()) +} + +pub const ROUTER: Router = Router::new() + .get(&API_METHOD_LIST_REMOTES) + .post(&API_METHOD_CREATE_REMOTE) + .delete(&API_METHOD_DELETE_REMOTE); diff --git a/src/config/remotes.rs b/src/config/remotes.rs index d203dbf9..b1180993 100644 --- a/src/config/remotes.rs +++ b/src/config/remotes.rs @@ -1,7 +1,7 @@ use failure::*; use lazy_static::lazy_static; use std::collections::HashMap; -use serde::Deserialize; +use serde::{Serialize, Deserialize}; use proxmox::api::{api, schema::*}; @@ -15,14 +15,14 @@ lazy_static! { // fixme: define better schemas -const REMOTE_ID_SCHEMA: Schema = StringSchema::new("Remote ID.") +pub const REMOTE_ID_SCHEMA: Schema = StringSchema::new("Remote ID.") .min_length(3) .schema(); -const COMMENT_SCHEMA: Schema = StringSchema::new("Comment").schema(); -const REMOTE_HOST_SCHEMA: Schema = StringSchema::new("Host IP address or DNS name.").schema(); -const REMOTE_USERID_SCHEMA: Schema = StringSchema::new("User ID").schema(); -const REMOTE_PASSWORD_SCHEMA: Schema = StringSchema::new("Password or auth token.").schema(); +pub const COMMENT_SCHEMA: Schema = StringSchema::new("Comment").schema(); +pub const REMOTE_HOST_SCHEMA: Schema = StringSchema::new("Host IP address or DNS name.").schema(); +pub const REMOTE_USERID_SCHEMA: Schema = StringSchema::new("User ID").schema(); +pub const REMOTE_PASSWORD_SCHEMA: Schema = StringSchema::new("Password or auth token.").schema(); #[api( properties: { @@ -41,7 +41,7 @@ const REMOTE_PASSWORD_SCHEMA: Schema = StringSchema::new("Password or auth token }, } )] -#[derive(Deserialize)] +#[derive(Serialize,Deserialize)] /// Remote properties. pub struct Remote { pub comment: Option,