3 use proxmox
::tools
::fs
::{file_get_contents, file_set_contents}
;
5 use crate::api_schema
::*;
6 //use crate::api_schema::router::*;
7 use crate::api2
::types
::*;
9 use lazy_static
::lazy_static
;
11 use std
::sync
::{Arc, Mutex}
;
15 use serde_json
::{json, Value}
;
17 static RESOLV_CONF_FN
: &str = "/etc/resolv.conf";
19 fn read_etc_resolv_conf() -> Result
<Value
, Error
> {
21 let mut result
= json
!({}
);
25 let raw
= file_get_contents(RESOLV_CONF_FN
)?
;
27 result
["digest"] = Value
::from(proxmox
::tools
::digest_to_hex(&sha
::sha256(&raw
)));
29 let data
= String
::from_utf8(raw
)?
;
32 static ref DOMAIN_REGEX
: Regex
= Regex
::new(r
"^\s*(?:search|domain)\s+(\S+)\s*").unwrap();
33 static ref SERVER_REGEX
: Regex
= Regex
::new(
34 concat
!(r
"^\s*nameserver\s+(", IPRE
!(), r
")\s*")).unwrap();
37 for line
in data
.lines() {
39 if let Some(caps
) = DOMAIN_REGEX
.captures(&line
) {
40 result
["search"] = Value
::from(&caps
[1]);
41 } else if let Some(caps
) = SERVER_REGEX
.captures(&line
) {
43 if nscount
> 3 { continue }
;
44 let nameserver
= &caps
[1];
45 let id
= format
!("dns{}", nscount
);
46 result
[id
] = Value
::from(nameserver
);
56 _rpcenv
: &mut dyn RpcEnvironment
,
57 ) -> Result
<Value
, Error
> {
60 static ref MUTEX
: Arc
<Mutex
<usize>> = Arc
::new(Mutex
::new(0));
63 let _guard
= MUTEX
.lock();
65 let search
= crate::tools
::required_string_param(¶m
, "search")?
;
67 let raw
= file_get_contents(RESOLV_CONF_FN
)?
;
68 let old_digest
= proxmox
::tools
::digest_to_hex(&sha
::sha256(&raw
));
70 if let Some(digest
) = param
["digest"].as_str() {
71 crate::tools
::assert_if_modified(&old_digest
, &digest
)?
;
74 let old_data
= String
::from_utf8(raw
)?
;
76 let mut data
= format
!("search {}\n", search
);
78 for opt
in &["dns1", "dns2", "dns3"] {
79 if let Some(server
) = param
[opt
].as_str() {
80 data
.push_str(&format
!("nameserver {}\n", server
));
86 static ref SKIP_REGEX
: Regex
= Regex
::new(r
"^(search|domain|nameserver)\s+").unwrap();
88 for line
in old_data
.lines() {
89 if SKIP_REGEX
.is_match(line
) { continue; }
94 file_set_contents(RESOLV_CONF_FN
, data
.as_bytes(), None
)?
;
102 _rpcenv
: &mut dyn RpcEnvironment
,
103 ) -> Result
<Value
, Error
> {
105 read_etc_resolv_conf()
108 pub fn router() -> Router
{
110 let route
= Router
::new()
114 ObjectSchema
::new("Read DNS settings.")
115 .required("node", NODE_SCHEMA
.clone())
117 ObjectSchema
::new("Returns DNS server IPs and sreach domain.")
118 .required("digest", PVE_CONFIG_DIGEST_SCHEMA
.clone())
119 .optional("search", SEARCH_DOMAIN_SCHEMA
.clone())
120 .optional("dns1", FIRST_DNS_SERVER_SCHEMA
.clone())
121 .optional("dns2", SECOND_DNS_SERVER_SCHEMA
.clone())
122 .optional("dns3", THIRD_DNS_SERVER_SCHEMA
.clone())
128 ObjectSchema
::new("Returns DNS server IPs and sreach domain.")
129 .required("node", NODE_SCHEMA
.clone())
130 .required("search", SEARCH_DOMAIN_SCHEMA
.clone())
131 .optional("dns1", FIRST_DNS_SERVER_SCHEMA
.clone())
132 .optional("dns2", SECOND_DNS_SERVER_SCHEMA
.clone())
133 .optional("dns3", THIRD_DNS_SERVER_SCHEMA
.clone())
134 .optional("digest", PVE_CONFIG_DIGEST_SCHEMA
.clone())