1 use anyhow
::{bail, Error}
;
4 use proxmox
::api
::{api, ApiMethod, Router, RpcEnvironment, Permission}
;
6 use crate::api2
::types
::*;
7 use crate::config
::remote
;
8 use crate::config
::acl
::{PRIV_SYS_AUDIT, PRIV_SYS_MODIFY}
;
15 description
: "The list of configured remotes (with config digest).",
19 description
: "Remote configuration (without password).",
22 schema
: REMOTE_ID_SCHEMA
,
26 schema
: SINGLE_LINE_COMMENT_SCHEMA
,
29 schema
: DNS_NAME_OR_IP_SCHEMA
,
32 schema
: PROXMOX_USER_ID_SCHEMA
,
36 schema
: CERT_FINGERPRINT_SHA256_SCHEMA
,
42 permission
: &Permission
::Privilege(&[], PRIV_SYS_AUDIT
, false),
49 _rpcenv
: &mut dyn RpcEnvironment
,
50 ) -> Result
<Value
, Error
> {
52 let (config
, digest
) = remote
::config()?
;
54 let value
= config
.convert_to_array("name", Some(&digest
), &["password"]);
64 schema
: REMOTE_ID_SCHEMA
,
68 schema
: SINGLE_LINE_COMMENT_SCHEMA
,
71 schema
: DNS_NAME_OR_IP_SCHEMA
,
74 schema
: PROXMOX_USER_ID_SCHEMA
,
77 schema
: remote
::REMOTE_PASSWORD_SCHEMA
,
81 schema
: CERT_FINGERPRINT_SHA256_SCHEMA
,
86 permission
: &Permission
::Privilege(&[], PRIV_SYS_MODIFY
, false),
89 /// Create new remote.
90 pub fn create_remote(name
: String
, param
: Value
) -> Result
<(), Error
> {
92 let _lock
= crate::tools
::open_file_locked(remote
::REMOTE_CFG_LOCKFILE
, std
::time
::Duration
::new(10, 0))?
;
94 let remote
: remote
::Remote
= serde_json
::from_value(param
.clone())?
;
96 let (mut config
, _digest
) = remote
::config()?
;
98 if let Some(_
) = config
.sections
.get(&name
) {
99 bail
!("remote '{}' already exists.", name
);
102 config
.set_data(&name
, "remote", &remote
)?
;
104 remote
::save_config(&config
)?
;
113 schema
: REMOTE_ID_SCHEMA
,
118 description
: "The remote configuration (with config digest).",
119 type: remote
::Remote
,
122 permission
: &Permission
::Privilege(&[], PRIV_SYS_AUDIT
, false),
125 /// Read remote configuration data.
126 pub fn read_remote(name
: String
) -> Result
<Value
, Error
> {
127 let (config
, digest
) = remote
::config()?
;
128 let mut data
= config
.lookup_json("remote", &name
)?
;
129 data
.as_object_mut().unwrap()
130 .insert("digest".into(), proxmox
::tools
::digest_to_hex(&digest
).into());
139 schema
: REMOTE_ID_SCHEMA
,
143 schema
: SINGLE_LINE_COMMENT_SCHEMA
,
147 schema
: DNS_NAME_OR_IP_SCHEMA
,
151 schema
: PROXMOX_USER_ID_SCHEMA
,
155 schema
: remote
::REMOTE_PASSWORD_SCHEMA
,
159 schema
: CERT_FINGERPRINT_SHA256_SCHEMA
,
163 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
168 permission
: &Permission
::Privilege(&[], PRIV_SYS_MODIFY
, false),
171 /// Update remote configuration.
172 pub fn update_remote(
174 comment
: Option
<String
>,
175 host
: Option
<String
>,
176 userid
: Option
<String
>,
177 password
: Option
<String
>,
178 fingerprint
: Option
<String
>,
179 digest
: Option
<String
>,
180 ) -> Result
<(), Error
> {
182 let _lock
= crate::tools
::open_file_locked(remote
::REMOTE_CFG_LOCKFILE
, std
::time
::Duration
::new(10, 0))?
;
184 let (mut config
, expected_digest
) = remote
::config()?
;
186 if let Some(ref digest
) = digest
{
187 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
188 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
191 let mut data
: remote
::Remote
= config
.lookup("remote", &name
)?
;
193 if let Some(comment
) = comment
{
194 let comment
= comment
.trim().to_string();
195 if comment
.is_empty() {
198 data
.comment
= Some(comment
);
201 if let Some(host
) = host { data.host = host; }
202 if let Some(userid
) = userid { data.userid = userid; }
203 if let Some(password
) = password { data.password = password; }
205 // fixme: howto delete a fingeprint?
206 if let Some(fingerprint
) = fingerprint { data.fingerprint = Some(fingerprint); }
208 config
.set_data(&name
, "remote", &data
)?
;
210 remote
::save_config(&config
)?
;
220 schema
: REMOTE_ID_SCHEMA
,
225 permission
: &Permission
::Privilege(&[], PRIV_SYS_MODIFY
, false),
228 /// Remove a remote from the configuration file.
229 pub fn delete_remote(name
: String
) -> Result
<(), Error
> {
232 // fixme: check digest ?
234 let (mut config
, _digest
) = remote
::config()?
;
236 match config
.sections
.get(&name
) {
237 Some(_
) => { config.sections.remove(&name); }
,
238 None
=> bail
!("remote '{}' does not exist.", name
),
244 const ITEM_ROUTER
: Router
= Router
::new()
245 .get(&API_METHOD_READ_REMOTE
)
246 .put(&API_METHOD_UPDATE_REMOTE
)
247 .delete(&API_METHOD_DELETE_REMOTE
);
249 pub const ROUTER
: Router
= Router
::new()
250 .get(&API_METHOD_LIST_REMOTES
)
251 .post(&API_METHOD_CREATE_REMOTE
)
252 .match_all("name", &ITEM_ROUTER
);