src/bin/proxmox-backup-client.rs: add output-fromat options, implement status api

This commit is contained in:
Dietmar Maurer 2019-07-16 13:35:25 +02:00
parent 0eecf38fbf
commit 34a816cc7b
1 changed files with 85 additions and 5 deletions

View File

@ -294,6 +294,10 @@ fn list_backup_groups(
} }
}); });
let output_format = param["output-format"].as_str().unwrap_or("text").to_owned();
let mut result = vec![];
for item in list { for item in list {
let id = item["backup-id"].as_str().unwrap(); let id = item["backup-id"].as_str().unwrap();
@ -309,11 +313,22 @@ fn list_backup_groups(
let files = item["files"].as_array().unwrap().iter().map(|v| v.as_str().unwrap().to_owned()).collect(); let files = item["files"].as_array().unwrap().iter().map(|v| v.as_str().unwrap().to_owned()).collect();
let files = strip_server_file_expenstions(files); let files = strip_server_file_expenstions(files);
println!("{:20} | {} | {:5} | {}", path, last_backup.format("%c"), if output_format == "text" {
backup_count, tools::join(&files, ' ')); println!("{:20} | {} | {:5} | {}", path, last_backup.format("%c"),
backup_count, tools::join(&files, ' '));
} else {
result.push(json!({
"backup-type": btype,
"backup-id": id,
"last-backup": epoch,
"backup-count": backup_count,
"files": files,
}));
}
} }
//Ok(result) if output_format != "text" { format_and_print_result(result.into(), &output_format); }
Ok(Value::Null) Ok(Value::Null)
} }
@ -328,6 +343,8 @@ fn list_snapshots(
let path = tools::required_string_param(&param, "group")?; let path = tools::required_string_param(&param, "group")?;
let group = BackupGroup::parse(path)?; let group = BackupGroup::parse(path)?;
let output_format = param["output-format"].as_str().unwrap_or("text").to_owned();
let client = HttpClient::new(repo.host(), repo.user())?; let client = HttpClient::new(repo.host(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/snapshots", repo.store()); let path = format!("api2/json/admin/datastore/{}/snapshots", repo.store());
@ -339,9 +356,10 @@ fn list_snapshots(
record_repository(&repo); record_repository(&repo);
// fixme: implement and use output formatter instead ..
let list = result["data"].as_array().unwrap(); let list = result["data"].as_array().unwrap();
let mut result = vec![];
for item in list { for item in list {
let id = item["backup-id"].as_str().unwrap(); let id = item["backup-id"].as_str().unwrap();
@ -355,9 +373,20 @@ fn list_snapshots(
let files = item["files"].as_array().unwrap().iter().map(|v| v.as_str().unwrap().to_owned()).collect(); let files = item["files"].as_array().unwrap().iter().map(|v| v.as_str().unwrap().to_owned()).collect();
let files = strip_server_file_expenstions(files); let files = strip_server_file_expenstions(files);
println!("{} | {} | {}", path, snapshot.backup_time().format("%c"), tools::join(&files, ' ')); if output_format == "text" {
println!("{} | {} | {}", path, snapshot.backup_time().format("%c"), tools::join(&files, ' '));
} else {
result.push(json!({
"backup-type": btype,
"backup-id": id,
"backup-time": epoch,
"files": files,
}));
}
} }
if output_format != "text" { format_and_print_result(result.into(), &output_format); }
Ok(Value::Null) Ok(Value::Null)
} }
@ -775,6 +804,45 @@ fn prune(
Ok(result) Ok(result)
} }
fn status(
param: Value,
_info: &ApiMethod,
_rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
let repo = extract_repository_from_value(&param)?;
let output_format = param["output-format"].as_str().unwrap_or("text").to_owned();
let client = HttpClient::new(repo.host(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/status", repo.store());
let result = client.get(&path, None).wait()?;
let data = &result["data"];
record_repository(&repo);
if output_format == "text" {
let total = data["total"].as_u64().unwrap();
let used = data["used"].as_u64().unwrap();
let avail = data["avail"].as_u64().unwrap();
let roundup = total/200;
println!(
"total: {} used: {} ({} %) available: {}",
total,
used,
((used+roundup)*100)/total,
avail,
);
} else {
format_and_print_result(result, &output_format);
}
Ok(Value::Null)
}
// like get, but simply ignore errors and return Null instead // like get, but simply ignore errors and return Null instead
fn try_get(repo: &BackupRepository, url: &str) -> Value { fn try_get(repo: &BackupRepository, url: &str) -> Value {
@ -1215,6 +1283,7 @@ fn main() {
list_backup_groups, list_backup_groups,
ObjectSchema::new("List backup groups.") ObjectSchema::new("List backup groups.")
.optional("repository", REPO_URL_SCHEMA.clone()) .optional("repository", REPO_URL_SCHEMA.clone())
.optional("output-format", OUTPUT_FORMAT.clone())
)) ))
.completion_cb("repository", complete_repository); .completion_cb("repository", complete_repository);
@ -1224,6 +1293,7 @@ fn main() {
ObjectSchema::new("List backup snapshots.") ObjectSchema::new("List backup snapshots.")
.required("group", StringSchema::new("Backup group.")) .required("group", StringSchema::new("Backup group."))
.optional("repository", REPO_URL_SCHEMA.clone()) .optional("repository", REPO_URL_SCHEMA.clone())
.optional("output-format", OUTPUT_FORMAT.clone())
)) ))
.arg_param(vec!["group"]) .arg_param(vec!["group"])
.completion_cb("group", complete_backup_group) .completion_cb("group", complete_backup_group)
@ -1283,6 +1353,15 @@ We do not extraxt '.pxar' archives when writing to stdandard output.
)) ))
.completion_cb("repository", complete_repository); .completion_cb("repository", complete_repository);
let status_cmd_def = CliCommand::new(
ApiMethod::new(
status,
ObjectSchema::new("Get repository status.")
.optional("repository", REPO_URL_SCHEMA.clone())
.optional("output-format", OUTPUT_FORMAT.clone())
))
.completion_cb("repository", complete_repository);
let cmd_def = CliCommandMap::new() let cmd_def = CliCommandMap::new()
.insert("backup".to_owned(), backup_cmd_def.into()) .insert("backup".to_owned(), backup_cmd_def.into())
.insert("forget".to_owned(), forget_cmd_def.into()) .insert("forget".to_owned(), forget_cmd_def.into())
@ -1291,6 +1370,7 @@ We do not extraxt '.pxar' archives when writing to stdandard output.
.insert("prune".to_owned(), prune_cmd_def.into()) .insert("prune".to_owned(), prune_cmd_def.into())
.insert("restore".to_owned(), restore_cmd_def.into()) .insert("restore".to_owned(), restore_cmd_def.into())
.insert("snapshots".to_owned(), snapshots_cmd_def.into()) .insert("snapshots".to_owned(), snapshots_cmd_def.into())
.insert("status".to_owned(), status_cmd_def.into())
.insert("key".to_owned(), key_mgmt_cli().into()); .insert("key".to_owned(), key_mgmt_cli().into());
hyper::rt::run(futures::future::lazy(move || { hyper::rt::run(futures::future::lazy(move || {