2 use lazy_static
::lazy_static
;
3 use std
::collections
::HashMap
;
4 use serde
::{Serialize, Deserialize}
;
16 use proxmox
::tools
::{fs::replace_file, fs::CreateOptions}
;
18 use crate::api2
::types
::*;
21 static ref CONFIG
: SectionConfig
= init();
24 pub const REMOTE_PASSWORD_SCHEMA
: Schema
= StringSchema
::new("Password or auth token for remote host.")
25 .format(&PASSWORD_FORMAT
)
33 schema
: REMOTE_ID_SCHEMA
,
37 schema
: SINGLE_LINE_COMMENT_SCHEMA
,
40 schema
: DNS_NAME_OR_IP_SCHEMA
,
44 description
: "The (optional) port",
51 schema
: REMOTE_PASSWORD_SCHEMA
,
55 schema
: CERT_FINGERPRINT_SHA256_SCHEMA
,
59 #[derive(Serialize,Deserialize)]
60 #[serde(rename_all = "kebab-case")]
61 /// Remote properties.
64 #[serde(skip_serializing_if="Option::is_none")]
65 pub comment
: Option
<String
>,
67 #[serde(skip_serializing_if="Option::is_none")]
68 pub port
: Option
<u16>,
70 #[serde(skip_serializing_if="String::is_empty")]
71 #[serde(with = "proxmox::tools::serde::string_as_base64")]
73 #[serde(skip_serializing_if="Option::is_none")]
74 pub fingerprint
: Option
<String
>,
77 fn init() -> SectionConfig
{
78 let obj_schema
= match Remote
::API_SCHEMA
{
79 Schema
::Object(ref obj_schema
) => obj_schema
,
83 let plugin
= SectionConfigPlugin
::new("remote".to_string(), Some("name".to_string()), obj_schema
);
84 let mut config
= SectionConfig
::new(&REMOTE_ID_SCHEMA
);
85 config
.register_plugin(plugin
);
90 pub const REMOTE_CFG_FILENAME
: &str = "/etc/proxmox-backup/remote.cfg";
91 pub const REMOTE_CFG_LOCKFILE
: &str = "/etc/proxmox-backup/.remote.lck";
93 pub fn config() -> Result
<(SectionConfigData
, [u8;32]), Error
> {
95 let content
= proxmox
::tools
::fs
::file_read_optional_string(REMOTE_CFG_FILENAME
)?
;
96 let content
= content
.unwrap_or(String
::from(""));
98 let digest
= openssl
::sha
::sha256(content
.as_bytes());
99 let data
= CONFIG
.parse(REMOTE_CFG_FILENAME
, &content
)?
;
103 pub fn save_config(config
: &SectionConfigData
) -> Result
<(), Error
> {
104 let raw
= CONFIG
.write(REMOTE_CFG_FILENAME
, &config
)?
;
106 let backup_user
= crate::backup
::backup_user()?
;
107 let mode
= nix
::sys
::stat
::Mode
::from_bits_truncate(0o0640);
108 // set the correct owner/group/permissions while saving file
109 // owner(rw) = root, group(r)= backup
110 let options
= CreateOptions
::new()
112 .owner(nix
::unistd
::ROOT
)
113 .group(backup_user
.gid
);
115 replace_file(REMOTE_CFG_FILENAME
, raw
.as_bytes(), options
)?
;
120 // shell completion helper
121 pub fn complete_remote_name(_arg
: &str, _param
: &HashMap
<String
, String
>) -> Vec
<String
> {
123 Ok((data
, _digest
)) => data
.sections
.iter().map(|(id
, _
)| id
.to_string()).collect(),
124 Err(_
) => return vec
![],