]>
Commit | Line | Data |
---|---|---|
e7cb4dc5 | 1 | use std::convert::TryFrom; |
cad540e9 | 2 | use std::fmt; |
151c6ce2 | 3 | |
f7d4e4b5 | 4 | use anyhow::{format_err, Error}; |
151c6ce2 | 5 | |
75f83c6a | 6 | use pbs_api_types::{BACKUP_REPO_URL_REGEX, IP_V6_REGEX, Authid, Userid}; |
255f378a | 7 | |
151c6ce2 DM |
8 | /// Reference remote backup locations |
9 | /// | |
10 | ||
11 | #[derive(Debug)] | |
12 | pub struct BackupRepository { | |
13 | /// The user name used for Authentication | |
34aa8e13 | 14 | auth_id: Option<Authid>, |
151c6ce2 | 15 | /// The host name or IP address |
d0a03d40 | 16 | host: Option<String>, |
ba20987a DC |
17 | /// The port |
18 | port: Option<u16>, | |
151c6ce2 | 19 | /// The name of the datastore |
d0a03d40 | 20 | store: String, |
151c6ce2 DM |
21 | } |
22 | ||
23 | impl BackupRepository { | |
24 | ||
34aa8e13 | 25 | pub fn new(auth_id: Option<Authid>, host: Option<String>, port: Option<u16>, store: String) -> Self { |
38d46759 DC |
26 | let host = match host { |
27 | Some(host) if (IP_V6_REGEX.regex_obj)().is_match(&host) => { | |
28 | Some(format!("[{}]", host)) | |
29 | }, | |
30 | other => other, | |
31 | }; | |
34aa8e13 FG |
32 | Self { auth_id, host, port, store } |
33 | } | |
34 | ||
35 | pub fn auth_id(&self) -> &Authid { | |
36 | if let Some(ref auth_id) = self.auth_id { | |
37 | return auth_id; | |
38 | } | |
39 | ||
40 | &Authid::root_auth_id() | |
25de1c80 DM |
41 | } |
42 | ||
e7cb4dc5 | 43 | pub fn user(&self) -> &Userid { |
34aa8e13 FG |
44 | if let Some(auth_id) = &self.auth_id { |
45 | return auth_id.user(); | |
d0a03d40 | 46 | } |
34aa8e13 | 47 | |
e7cb4dc5 | 48 | Userid::root_userid() |
d0a03d40 DM |
49 | } |
50 | ||
51 | pub fn host(&self) -> &str { | |
52 | if let Some(ref host) = self.host { | |
53 | return host; | |
54 | } | |
55 | "localhost" | |
56 | } | |
57 | ||
ba20987a DC |
58 | pub fn port(&self) -> u16 { |
59 | if let Some(port) = self.port { | |
60 | return port; | |
61 | } | |
62 | 8007 | |
63 | } | |
64 | ||
d0a03d40 DM |
65 | pub fn store(&self) -> &str { |
66 | &self.store | |
67 | } | |
874acb70 | 68 | } |
d0a03d40 | 69 | |
874acb70 DM |
70 | impl fmt::Display for BackupRepository { |
71 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
34aa8e13 FG |
72 | match (&self.auth_id, &self.host, self.port) { |
73 | (Some(auth_id), _, _) => write!(f, "{}@{}:{}:{}", auth_id, self.host(), self.port(), self.store), | |
ba20987a DC |
74 | (None, Some(host), None) => write!(f, "{}:{}", host, self.store), |
75 | (None, _, Some(port)) => write!(f, "{}:{}:{}", self.host(), port, self.store), | |
76 | (None, None, None) => write!(f, "{}", self.store), | |
77 | } | |
d0a03d40 | 78 | } |
151c6ce2 | 79 | } |
edd3c8c6 DM |
80 | |
81 | impl std::str::FromStr for BackupRepository { | |
82 | type Err = Error; | |
83 | ||
84 | /// Parse a repository URL. | |
85 | /// | |
86 | /// This parses strings like `user@host:datastore`. The `user` and | |
87 | /// `host` parts are optional, where `host` defaults to the local | |
88 | /// host, and `user` defaults to `root@pam`. | |
89 | fn from_str(url: &str) -> Result<Self, Self::Err> { | |
90 | ||
255f378a | 91 | let cap = (BACKUP_REPO_URL_REGEX.regex_obj)().captures(url) |
edd3c8c6 DM |
92 | .ok_or_else(|| format_err!("unable to parse repository url '{}'", url))?; |
93 | ||
94 | Ok(Self { | |
34aa8e13 | 95 | auth_id: cap.get(1).map(|m| Authid::try_from(m.as_str().to_owned())).transpose()?, |
edd3c8c6 | 96 | host: cap.get(2).map(|m| m.as_str().to_owned()), |
ba20987a DC |
97 | port: cap.get(3).map(|m| m.as_str().parse::<u16>()).transpose()?, |
98 | store: cap[4].to_owned(), | |
edd3c8c6 DM |
99 | }) |
100 | } | |
101 | } |