]> git.proxmox.com Git - proxmox-backup.git/blame - src/api2/node/dns.rs
use const api definitions
[proxmox-backup.git] / src / api2 / node / dns.rs
CommitLineData
b2b3485d
DM
1use failure::*;
2
e18a6c9e 3use proxmox::tools::fs::{file_get_contents, file_set_contents};
7f66c29e
DM
4use proxmox::tools::*; // required to use IPRE!() macro ???
5
46b79b9e 6use crate::api2::*;
4ebf0eab 7use crate::api_schema::*;
dc9a007b 8//use crate::api_schema::router::*;
4ebf0eab 9use crate::api2::types::*;
8f973f81
DM
10
11use lazy_static::lazy_static;
12
af2fddea 13use std::sync::{Arc, Mutex};
de6b0721 14use openssl::sha;
af2fddea 15use regex::Regex;
8f973f81 16
b2b3485d
DM
17use serde_json::{json, Value};
18
8f973f81
DM
19static RESOLV_CONF_FN: &str = "/etc/resolv.conf";
20
21fn read_etc_resolv_conf() -> Result<Value, Error> {
22
23 let mut result = json!({});
24
25 let mut nscount = 0;
26
e18a6c9e 27 let raw = file_get_contents(RESOLV_CONF_FN)?;
8f973f81 28
bffd40d6 29 result["digest"] = Value::from(proxmox::tools::digest_to_hex(&sha::sha256(&raw)));
de6b0721
DM
30
31 let data = String::from_utf8(raw)?;
8f973f81
DM
32
33 lazy_static! {
af2fddea
DM
34 static ref DOMAIN_REGEX: Regex = Regex::new(r"^\s*(?:search|domain)\s+(\S+)\s*").unwrap();
35 static ref SERVER_REGEX: Regex = Regex::new(
8f973f81
DM
36 concat!(r"^\s*nameserver\s+(", IPRE!(), r")\s*")).unwrap();
37 }
38
de6b0721 39 for line in data.lines() {
8f973f81 40
46b79b9e
DM
41 if let Some(caps) = DOMAIN_REGEX.captures(&line) {
42 result["search"] = Value::from(&caps[1]);
43 } else if let Some(caps) = SERVER_REGEX.captures(&line) {
8f973f81
DM
44 nscount += 1;
45 if nscount > 3 { continue };
46b79b9e 46 let nameserver = &caps[1];
8f973f81 47 let id = format!("dns{}", nscount);
46b79b9e 48 result[id] = Value::from(nameserver);
8f973f81
DM
49 }
50 }
51
52 Ok(result)
53}
b2b3485d 54
6049b71f
DM
55fn update_dns(
56 param: Value,
57 _info: &ApiMethod,
dd5495d6 58 _rpcenv: &mut dyn RpcEnvironment,
6049b71f 59) -> Result<Value, Error> {
46b79b9e 60
af2fddea
DM
61 lazy_static! {
62 static ref MUTEX: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
63 }
64
9f49fe1d 65 let _guard = MUTEX.lock();
af2fddea 66
e18a6c9e 67 let search = crate::tools::required_string_param(&param, "search")?;
46b79b9e 68
e18a6c9e 69 let raw = file_get_contents(RESOLV_CONF_FN)?;
bffd40d6 70 let old_digest = proxmox::tools::digest_to_hex(&sha::sha256(&raw));
af2fddea
DM
71
72 if let Some(digest) = param["digest"].as_str() {
e18a6c9e 73 crate::tools::assert_if_modified(&old_digest, &digest)?;
af2fddea
DM
74 }
75
76 let old_data = String::from_utf8(raw)?;
77
46b79b9e
DM
78 let mut data = format!("search {}\n", search);
79
80 for opt in &["dns1", "dns2", "dns3"] {
81 if let Some(server) = param[opt].as_str() {
82 data.push_str(&format!("nameserver {}\n", server));
83 }
84 }
85
af2fddea
DM
86 // append other data
87 lazy_static! {
88 static ref SKIP_REGEX: Regex = Regex::new(r"^(search|domain|nameserver)\s+").unwrap();
89 }
90 for line in old_data.lines() {
91 if SKIP_REGEX.is_match(line) { continue; }
92 data.push_str(line);
93 data.push('\n');
94 }
95
e18a6c9e 96 file_set_contents(RESOLV_CONF_FN, data.as_bytes(), None)?;
46b79b9e
DM
97
98 Ok(Value::Null)
99}
100
6049b71f
DM
101fn get_dns(
102 _param: Value,
103 _info: &ApiMethod,
dd5495d6 104 _rpcenv: &mut dyn RpcEnvironment,
6049b71f 105) -> Result<Value, Error> {
b2b3485d 106
8f973f81 107 read_etc_resolv_conf()
b2b3485d
DM
108}
109
255f378a
DM
110pub const ROUTER: Router = Router::new()
111 .get(
112 &ApiMethod::new(
113 &ApiHandler::Sync(&get_dns),
114 &ObjectSchema::new(
115 "Read DNS settings.",
116 &[ ("node", false, &NODE_SCHEMA) ],
8f973f81 117 )
255f378a
DM
118 ).returns(
119 &ObjectSchema::new(
120 "Returns DNS server IPs and sreach domain.",
121 &[
122 ("digest", false, &PVE_CONFIG_DIGEST_SCHEMA),
123 ("search", true, &SEARCH_DOMAIN_SCHEMA),
124 ("dns1", true, &FIRST_DNS_SERVER_SCHEMA),
125 ("dns2", true, &SECOND_DNS_SERVER_SCHEMA),
126 ("dns3", true, &THIRD_DNS_SERVER_SCHEMA),
127 ],
128 ).schema()
46b79b9e 129 )
255f378a
DM
130 )
131 .put(
132 &ApiMethod::new(
133 &ApiHandler::Sync(&update_dns),
134 &ObjectSchema::new(
135 "Returns DNS server IPs and sreach domain.",
136 &[
137 ("node", false, &NODE_SCHEMA),
138 ("search", false, &SEARCH_DOMAIN_SCHEMA),
139 ("dns1", true, &FIRST_DNS_SERVER_SCHEMA),
140 ("dns2", true, &SECOND_DNS_SERVER_SCHEMA),
141 ("dns3", true, &THIRD_DNS_SERVER_SCHEMA),
142 ("digest", true, &PVE_CONFIG_DIGEST_SCHEMA),
143 ],
144 )
145 ).protected(true)
146 );