]>
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 | |
bdfa6370 | 6 | use pbs_api_types::{Authid, Userid, BACKUP_REPO_URL_REGEX, IP_V6_REGEX}; |
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 { | |
bdfa6370 TL |
24 | pub fn new( |
25 | auth_id: Option<Authid>, | |
26 | host: Option<String>, | |
27 | port: Option<u16>, | |
28 | store: String, | |
29 | ) -> Self { | |
38d46759 | 30 | let host = match host { |
bdfa6370 | 31 | Some(host) if (IP_V6_REGEX.regex_obj)().is_match(&host) => Some(format!("[{}]", host)), |
38d46759 DC |
32 | other => other, |
33 | }; | |
bdfa6370 TL |
34 | Self { |
35 | auth_id, | |
36 | host, | |
37 | port, | |
38 | store, | |
39 | } | |
34aa8e13 FG |
40 | } |
41 | ||
42 | pub fn auth_id(&self) -> &Authid { | |
43 | if let Some(ref auth_id) = self.auth_id { | |
44 | return auth_id; | |
45 | } | |
46 | ||
9a37bd6c | 47 | Authid::root_auth_id() |
25de1c80 DM |
48 | } |
49 | ||
e7cb4dc5 | 50 | pub fn user(&self) -> &Userid { |
34aa8e13 FG |
51 | if let Some(auth_id) = &self.auth_id { |
52 | return auth_id.user(); | |
d0a03d40 | 53 | } |
34aa8e13 | 54 | |
e7cb4dc5 | 55 | Userid::root_userid() |
d0a03d40 DM |
56 | } |
57 | ||
58 | pub fn host(&self) -> &str { | |
59 | if let Some(ref host) = self.host { | |
60 | return host; | |
61 | } | |
62 | "localhost" | |
63 | } | |
64 | ||
ba20987a DC |
65 | pub fn port(&self) -> u16 { |
66 | if let Some(port) = self.port { | |
67 | return port; | |
68 | } | |
69 | 8007 | |
70 | } | |
71 | ||
d0a03d40 DM |
72 | pub fn store(&self) -> &str { |
73 | &self.store | |
74 | } | |
874acb70 | 75 | } |
d0a03d40 | 76 | |
874acb70 DM |
77 | impl fmt::Display for BackupRepository { |
78 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
34aa8e13 | 79 | match (&self.auth_id, &self.host, self.port) { |
bdfa6370 TL |
80 | (Some(auth_id), _, _) => write!( |
81 | f, | |
82 | "{}@{}:{}:{}", | |
83 | auth_id, | |
84 | self.host(), | |
85 | self.port(), | |
86 | self.store | |
87 | ), | |
ba20987a DC |
88 | (None, Some(host), None) => write!(f, "{}:{}", host, self.store), |
89 | (None, _, Some(port)) => write!(f, "{}:{}:{}", self.host(), port, self.store), | |
90 | (None, None, None) => write!(f, "{}", self.store), | |
91 | } | |
d0a03d40 | 92 | } |
151c6ce2 | 93 | } |
edd3c8c6 DM |
94 | |
95 | impl std::str::FromStr for BackupRepository { | |
96 | type Err = Error; | |
97 | ||
98 | /// Parse a repository URL. | |
99 | /// | |
100 | /// This parses strings like `user@host:datastore`. The `user` and | |
101 | /// `host` parts are optional, where `host` defaults to the local | |
102 | /// host, and `user` defaults to `root@pam`. | |
103 | fn from_str(url: &str) -> Result<Self, Self::Err> { | |
bdfa6370 TL |
104 | let cap = (BACKUP_REPO_URL_REGEX.regex_obj)() |
105 | .captures(url) | |
edd3c8c6 DM |
106 | .ok_or_else(|| format_err!("unable to parse repository url '{}'", url))?; |
107 | ||
108 | Ok(Self { | |
bdfa6370 TL |
109 | auth_id: cap |
110 | .get(1) | |
111 | .map(|m| Authid::try_from(m.as_str().to_owned())) | |
112 | .transpose()?, | |
edd3c8c6 | 113 | host: cap.get(2).map(|m| m.as_str().to_owned()), |
ba20987a DC |
114 | port: cap.get(3).map(|m| m.as_str().parse::<u16>()).transpose()?, |
115 | store: cap[4].to_owned(), | |
edd3c8c6 DM |
116 | }) |
117 | } | |
118 | } |