From 024f11bb55078ae5240c6e24eacbbc954b9d9613 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 13 Mar 2019 11:56:37 +0100 Subject: [PATCH] src/bin/proxmox-backup-client.rs: implement completion for backup groups --- src/bin/proxmox-backup-client.rs | 37 ++++++++++++++++++++++++++++++ src/client/http_client.rs | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 6bdee694..e51ba94a 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -581,6 +581,42 @@ fn prune( Ok(result) } +fn complete_backup_group(arg: &str, param: &HashMap) -> Vec { + + let mut result = vec![]; + + let repo_url = match param.get("repository") { + Some(v) => v, + _ => return result, + }; + + let repo: BackupRepository = match repo_url.parse() { + Ok(v) => v, + _ => return result, + }; + + let mut client = HttpClient::new(repo.host(), repo.user()); + + let path = format!("api2/json/admin/datastore/{}/groups", repo.store()); + + let resp = match client.try_get(&path) { + Ok(v) => v, + _ => return result, + }; + + if let Some(list) = resp["data"].as_array() { + for item in list { + if let Some(backup_id) = item["backup-id"].as_str() { + if let Some(backup_type) = item["backup-type"].as_str() { + result.push(format!("{}/{}", backup_type, backup_id)); + } + } + } + } + + result +} + fn main() { let repo_url_schema: Arc = Arc::new( @@ -643,6 +679,7 @@ fn main() { .required("group", StringSchema::new("Backup group.")) )) .arg_param(vec!["repository", "group"]) + .completion_cb("group", complete_backup_group) .completion_cb("repository", complete_repository); let forget_cmd_def = CliCommand::new( diff --git a/src/client/http_client.rs b/src/client/http_client.rs index a43ff3e9..27179ecc 100644 --- a/src/client/http_client.rs +++ b/src/client/http_client.rs @@ -257,6 +257,45 @@ impl HttpClient { Self::run_request(request) } + /// like get(), but use existing credentials (never asks for password). + /// this simply fails when there is no ticket + pub fn try_get(&mut self, path: &str) -> Result { + + let path = path.trim_matches('/'); + let url: Uri = format!("https://{}:8007/{}", self.server, path).parse()?; + + let mut credentials = None; + + if let Some(ref ticket) = self.ticket { + if let Some(ref token) = self.token { + credentials = Some((ticket.clone(), token.clone())); + } + } + + if credentials == None { + if let Some((ticket, token)) = load_ticket_info(&self.server, &self.username) { + credentials = Some((ticket.clone(), token.clone())); + } + } + + if credentials == None { + bail!("unable to get credentials"); + } + + let (ticket, _token) = credentials.unwrap(); + + let enc_ticket = percent_encode(ticket.as_bytes(), DEFAULT_ENCODE_SET).to_string(); + + let request = Request::builder() + .method("GET") + .uri(url) + .header("User-Agent", "proxmox-backup-client/1.0") + .header("Cookie", format!("PBSAuthCookie={}", enc_ticket)) + .body(Body::empty())?; + + Self::run_request(request) + } + pub fn delete(&mut self, path: &str) -> Result { let path = path.trim_matches('/');