]> git.proxmox.com Git - proxmox-backup.git/blob - pbs-config/src/traffic_control.rs
48e2a514759ad69b5d60777a7d44a6de88e6be2a
[proxmox-backup.git] / pbs-config / src / traffic_control.rs
1 //! Traffic Control Settings (Network rate limits)
2 use std::collections::HashMap;
3
4 use anyhow::Error;
5 use lazy_static::lazy_static;
6
7 use proxmox_schema::{ApiType, Schema};
8
9 use pbs_api_types::{TrafficControlRule, TRAFFIC_CONTROL_ID_SCHEMA};
10
11 use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
12
13 use crate::ConfigVersionCache;
14 use crate::{open_backup_lockfile, replace_backup_config, BackupLockGuard};
15
16 lazy_static! {
17 /// Static [`SectionConfig`] to access parser/writer functions.
18 pub static ref CONFIG: SectionConfig = init();
19 }
20
21 fn init() -> SectionConfig {
22 let mut config = SectionConfig::new(&TRAFFIC_CONTROL_ID_SCHEMA);
23
24 let obj_schema = match TrafficControlRule::API_SCHEMA {
25 Schema::AllOf(ref allof_schema) => allof_schema,
26 _ => unreachable!(),
27 };
28 let plugin = SectionConfigPlugin::new("rule".to_string(), Some("name".to_string()), obj_schema);
29 config.register_plugin(plugin);
30
31 config
32 }
33
34 /// Configuration file name
35 pub const TRAFFIC_CONTROL_CFG_FILENAME: &str = "/etc/proxmox-backup/traffic-control.cfg";
36 /// Lock file name (used to prevent concurrent access)
37 pub const TRAFFIC_CONTROL_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.traffic-control.lck";
38
39 /// Get exclusive lock
40 pub fn lock_config() -> Result<BackupLockGuard, Error> {
41 open_backup_lockfile(TRAFFIC_CONTROL_CFG_LOCKFILE, None, true)
42 }
43
44 /// Read and parse the configuration file
45 pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
46
47 let content = proxmox::tools::fs::file_read_optional_string(TRAFFIC_CONTROL_CFG_FILENAME)?
48 .unwrap_or_else(|| "".to_string());
49
50 let digest = openssl::sha::sha256(content.as_bytes());
51 let data = CONFIG.parse(TRAFFIC_CONTROL_CFG_FILENAME, &content)?;
52 Ok((data, digest))
53 }
54
55 /// Save the configuration file
56 pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
57 let raw = CONFIG.write(TRAFFIC_CONTROL_CFG_FILENAME, &config)?;
58 replace_backup_config(TRAFFIC_CONTROL_CFG_FILENAME, raw.as_bytes())?;
59
60 // increase traffic control version
61 // We use this in TrafficControlCache
62 let version_cache = ConfigVersionCache::new()?;
63 version_cache.increase_traffic_control_generation();
64
65 Ok(())
66 }
67
68
69 // shell completion helper
70 pub fn complete_traffic_control_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
71 match config() {
72 Ok((data, _digest)) => data.sections.iter().map(|(id, _)| id.to_string()).collect(),
73 Err(_) => return vec![],
74 }
75 }
76
77 #[cfg(test)]
78 mod test {
79 use super::*;
80
81 #[test]
82 fn test1() -> Result<(), Error> {
83 let content = "rule: rule1
84 comment localnet at working hours
85 network 192.168.2.0/24
86 network 192.168.3.0/24
87 rate-in 500000
88 timeframe mon..wed 8:00-16:30
89 timeframe fri 9:00-12:00
90 ";
91 let data = CONFIG.parse(TRAFFIC_CONTROL_CFG_FILENAME, &content)?;
92 eprintln!("GOT {:?}", data);
93
94 Ok(())
95 }
96
97 }