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