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