cleanup config api, add remotes config cli interface
This commit is contained in:
parent
9e9bc6525e
commit
688fbe07a1
@ -3,19 +3,26 @@ use std::path::PathBuf;
|
||||
use failure::*;
|
||||
use serde_json::Value;
|
||||
|
||||
use proxmox::api::{ApiHandler, ApiMethod, Router, RpcEnvironment};
|
||||
use proxmox::api::schema::*;
|
||||
use proxmox::api::{api, ApiMethod, Router, RpcEnvironment};
|
||||
|
||||
use crate::api2::types::*;
|
||||
use crate::backup::*;
|
||||
use crate::config::datastore;
|
||||
|
||||
pub const GET: ApiMethod = ApiMethod::new(
|
||||
&ApiHandler::Sync(&get_datastore_list),
|
||||
&ObjectSchema::new("Directory index.", &[])
|
||||
);
|
||||
|
||||
fn get_datastore_list(
|
||||
#[api(
|
||||
input: {
|
||||
properties: {},
|
||||
},
|
||||
returns: {
|
||||
description: "List the configured datastores.",
|
||||
type: Array,
|
||||
items: {
|
||||
type: datastore::DataStoreConfig,
|
||||
},
|
||||
},
|
||||
)]
|
||||
/// List all datastores
|
||||
pub fn list_datastores(
|
||||
_param: Value,
|
||||
_info: &ApiMethod,
|
||||
_rpcenv: &mut dyn RpcEnvironment,
|
||||
@ -26,90 +33,83 @@ fn get_datastore_list(
|
||||
Ok(config.convert_to_array("name"))
|
||||
}
|
||||
|
||||
pub const POST: ApiMethod = ApiMethod::new(
|
||||
&ApiHandler::Sync(&create_datastore),
|
||||
&ObjectSchema::new(
|
||||
"Create new datastore.",
|
||||
&[
|
||||
("comment", true, &StringSchema::new("Comment for this Datastore").schema()),
|
||||
("name", false, &DATASTORE_SCHEMA),
|
||||
("path", false, &StringSchema::new("Directory path. The directory path is created if it does not already exist.").schema()),
|
||||
],
|
||||
)
|
||||
).protected(true);
|
||||
|
||||
fn create_datastore(
|
||||
param: Value,
|
||||
_info: &ApiMethod,
|
||||
_rpcenv: &mut dyn RpcEnvironment,
|
||||
) -> Result<Value, Error> {
|
||||
#[api(
|
||||
protected: true,
|
||||
input: {
|
||||
properties: {
|
||||
name: {
|
||||
schema: DATASTORE_SCHEMA,
|
||||
},
|
||||
comment: {
|
||||
optional: true,
|
||||
schema: datastore::COMMENT_SCHEMA,
|
||||
},
|
||||
path: {
|
||||
schema: datastore::DIR_NAME_SCHEMA,
|
||||
},
|
||||
},
|
||||
},
|
||||
)]
|
||||
/// Create new datastore config.
|
||||
pub fn create_datastore(name: String, param: Value) -> Result<(), Error> {
|
||||
|
||||
// fixme: locking ?
|
||||
|
||||
let datastore: datastore::DataStoreConfig = serde_json::from_value(param.clone())?;
|
||||
|
||||
let mut config = datastore::config()?;
|
||||
|
||||
let name = param["name"].as_str().unwrap();
|
||||
|
||||
if let Some(_) = config.sections.get(name) {
|
||||
if let Some(_) = config.sections.get(&name) {
|
||||
bail!("datastore '{}' already exists.", name);
|
||||
}
|
||||
|
||||
let path: PathBuf = param["path"].as_str().unwrap().into();
|
||||
let backup_user = crate::backup::backup_user()?;
|
||||
let _store = ChunkStore::create(name, path, backup_user.uid, backup_user.gid)?;
|
||||
|
||||
let mut datastore = serde_json::Map::new();
|
||||
datastore.insert("path".to_string(), param["path"].clone());
|
||||
if let Some(comment) = param.get("comment") {
|
||||
if comment.as_str().unwrap().find(|c: char| c.is_control()).is_some() {
|
||||
if let Some(ref comment) = datastore.comment {
|
||||
if comment.find(|c: char| c.is_control()).is_some() {
|
||||
bail!("comment must not contain control characters!");
|
||||
}
|
||||
|
||||
datastore.insert("comment".to_string(), comment.clone());
|
||||
}
|
||||
|
||||
config.set_data(name, "datastore", Value::Object(datastore));
|
||||
let path: PathBuf = datastore.path.clone().into();
|
||||
|
||||
let backup_user = crate::backup::backup_user()?;
|
||||
let _store = ChunkStore::create(&name, path, backup_user.uid, backup_user.gid)?;
|
||||
|
||||
config.set_data(&name, "datastore", serde_json::to_value(datastore)?);
|
||||
|
||||
datastore::save_config(&config)?;
|
||||
|
||||
Ok(Value::Null)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub const DELETE: ApiMethod = ApiMethod::new(
|
||||
&ApiHandler::Sync(&delete_datastore),
|
||||
&ObjectSchema::new(
|
||||
"Remove a datastore configuration.",
|
||||
&[
|
||||
("name", false, &DATASTORE_SCHEMA),
|
||||
],
|
||||
)
|
||||
).protected(true);
|
||||
|
||||
fn delete_datastore(
|
||||
param: Value,
|
||||
_info: &ApiMethod,
|
||||
_rpcenv: &mut dyn RpcEnvironment,
|
||||
) -> Result<Value, Error> {
|
||||
println!("This is a test {}", param);
|
||||
#[api(
|
||||
protected: true,
|
||||
input: {
|
||||
properties: {
|
||||
name: {
|
||||
schema: DATASTORE_SCHEMA,
|
||||
},
|
||||
},
|
||||
},
|
||||
)]
|
||||
/// Remove a datastore configuration.
|
||||
pub fn delete_datastore(name: String) -> Result<(), Error> {
|
||||
|
||||
// fixme: locking ?
|
||||
// fixme: check digest ?
|
||||
|
||||
let mut config = datastore::config()?;
|
||||
|
||||
let name = param["name"].as_str().unwrap();
|
||||
|
||||
match config.sections.get(name) {
|
||||
Some(_) => { config.sections.remove(name); },
|
||||
match config.sections.get(&name) {
|
||||
Some(_) => { config.sections.remove(&name); },
|
||||
None => bail!("datastore '{}' does not exist.", name),
|
||||
}
|
||||
|
||||
datastore::save_config(&config)?;
|
||||
|
||||
Ok(Value::Null)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub const ROUTER: Router = Router::new()
|
||||
.get(&GET)
|
||||
.post(&POST)
|
||||
.delete(&DELETE);
|
||||
.get(&API_METHOD_LIST_DATASTORES)
|
||||
.post(&API_METHOD_CREATE_DATASTORE)
|
||||
.delete(&API_METHOD_DELETE_DATASTORE);
|
||||
|
@ -30,6 +30,7 @@ pub fn list_remotes(
|
||||
}
|
||||
|
||||
#[api(
|
||||
protected: true,
|
||||
input: {
|
||||
properties: {
|
||||
name: {
|
||||
@ -72,6 +73,7 @@ pub fn create_remote(name: String, param: Value) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[api(
|
||||
protected: true,
|
||||
input: {
|
||||
properties: {
|
||||
name: {
|
||||
|
@ -113,6 +113,7 @@ pub const UPID_SCHEMA: Schema = StringSchema::new("Unique Process/Task ID.")
|
||||
|
||||
pub const DATASTORE_SCHEMA: Schema = StringSchema::new("Datastore name.")
|
||||
.format(&PROXMOX_SAFE_ID_FORMAT)
|
||||
.min_length(3)
|
||||
.max_length(32)
|
||||
.schema();
|
||||
|
||||
|
@ -44,18 +44,40 @@ fn connect() -> Result<HttpClient, Error> {
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
fn remotes_commands() -> CommandLineInterface {
|
||||
|
||||
use proxmox_backup::api2;
|
||||
|
||||
let cmd_def = CliCommandMap::new()
|
||||
.insert("list", CliCommand::new(&api2::config::remotes::API_METHOD_LIST_REMOTES))
|
||||
.insert(
|
||||
"create",
|
||||
// fixme: howto handle password parameter?
|
||||
CliCommand::new(&api2::config::remotes::API_METHOD_CREATE_REMOTE)
|
||||
.arg_param(&["name"])
|
||||
)
|
||||
.insert(
|
||||
"remove",
|
||||
CliCommand::new(&api2::config::remotes::API_METHOD_DELETE_REMOTE)
|
||||
.arg_param(&["name"])
|
||||
.completion_cb("name", config::remotes::complete_remote_name)
|
||||
);
|
||||
|
||||
cmd_def.into()
|
||||
}
|
||||
|
||||
fn datastore_commands() -> CommandLineInterface {
|
||||
|
||||
use proxmox_backup::api2;
|
||||
|
||||
let cmd_def = CliCommandMap::new()
|
||||
.insert("list", CliCommand::new(&api2::config::datastore::GET))
|
||||
.insert("list", CliCommand::new(&api2::config::datastore::API_METHOD_LIST_DATASTORES))
|
||||
.insert("create",
|
||||
CliCommand::new(&api2::config::datastore::POST)
|
||||
CliCommand::new(&api2::config::datastore::API_METHOD_CREATE_DATASTORE)
|
||||
.arg_param(&["name", "path"])
|
||||
)
|
||||
.insert("remove",
|
||||
CliCommand::new(&api2::config::datastore::DELETE)
|
||||
CliCommand::new(&api2::config::datastore::API_METHOD_DELETE_DATASTORE)
|
||||
.arg_param(&["name"])
|
||||
.completion_cb("name", config::datastore::complete_datastore_name)
|
||||
);
|
||||
@ -360,8 +382,7 @@ fn cert_mgmt_cli() -> CommandLineInterface {
|
||||
schema: DATASTORE_SCHEMA,
|
||||
},
|
||||
remote: {
|
||||
description: "Remote name.", // fixme: remote ID schema
|
||||
type: String,
|
||||
schema: crate::config::remotes::REMOTE_ID_SCHEMA,
|
||||
},
|
||||
"remote-store": {
|
||||
schema: DATASTORE_SCHEMA,
|
||||
@ -407,6 +428,7 @@ fn main() {
|
||||
|
||||
let cmd_def = CliCommandMap::new()
|
||||
.insert("datastore", datastore_commands())
|
||||
.insert("remotes", remotes_commands())
|
||||
.insert("garbage-collection", garbage_collection_commands())
|
||||
.insert("cert", cert_mgmt_cli())
|
||||
.insert("task", task_mgmt_cli())
|
||||
|
@ -6,6 +6,7 @@ use serde::{Serialize, Deserialize};
|
||||
use proxmox::api::{api, schema::*};
|
||||
use proxmox::tools::{fs::replace_file, fs::CreateOptions};
|
||||
|
||||
use crate::api2::types::*;
|
||||
use crate::section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
|
||||
|
||||
lazy_static! {
|
||||
@ -16,9 +17,6 @@ lazy_static! {
|
||||
|
||||
pub const DIR_NAME_SCHEMA: Schema = StringSchema::new("Directory name").schema();
|
||||
pub const COMMENT_SCHEMA: Schema = StringSchema::new("Datastore comment").schema();
|
||||
pub const DATASTORE_ID_SCHEMA: Schema = StringSchema::new("DataStore ID schema.")
|
||||
.min_length(3)
|
||||
.schema();
|
||||
|
||||
#[api(
|
||||
properties: {
|
||||
@ -45,7 +43,7 @@ fn init() -> SectionConfig {
|
||||
};
|
||||
|
||||
let plugin = SectionConfigPlugin::new("datastore".to_string(), obj_schema);
|
||||
let mut config = SectionConfig::new(&DATASTORE_ID_SCHEMA);
|
||||
let mut config = SectionConfig::new(&DATASTORE_SCHEMA);
|
||||
config.register_plugin(plugin);
|
||||
|
||||
config
|
||||
|
Loading…
Reference in New Issue
Block a user