]> git.proxmox.com Git - proxmox-backup.git/blame - src/api2/config/traffic_control.rs
update to proxmox-sys 0.2 crate
[proxmox-backup.git] / src / api2 / config / traffic_control.rs
CommitLineData
bfd12e87
DM
1use anyhow::{bail, Error};
2use serde_json::Value;
3use ::serde::{Deserialize, Serialize};
25877d05 4use hex::FromHex;
bfd12e87
DM
5
6use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
7use proxmox_schema::api;
8
9use pbs_api_types::{
10 TrafficControlRule, TrafficControlRuleUpdater,
11 PROXMOX_CONFIG_DIGEST_SCHEMA, TRAFFIC_CONTROL_ID_SCHEMA,
12 PRIV_SYS_AUDIT, PRIV_SYS_MODIFY,
13};
14
15#[api(
16 input: {
17 properties: {},
18 },
19 returns: {
20 description: "The list of configured traffic control rules (with config digest).",
21 type: Array,
22 items: { type: TrafficControlRule },
23 },
24 access: {
25 permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
26 },
27)]
28/// List traffic control rules
29pub fn list_traffic_controls(
30 _param: Value,
31 _info: &ApiMethod,
32 mut rpcenv: &mut dyn RpcEnvironment,
33) -> Result<Vec<TrafficControlRule>, Error> {
34 let (config, digest) = pbs_config::traffic_control::config()?;
35
36 let list: Vec<TrafficControlRule> = config.convert_to_typed_array("rule")?;
37
25877d05 38 rpcenv["digest"] = hex::encode(&digest).into();
bfd12e87
DM
39
40 Ok(list)
41}
42
43#[api(
44 protected: true,
45 input: {
46 properties: {
47 config: {
48 type: TrafficControlRule,
49 flatten: true,
50 },
51 },
52 },
53 access: {
54 permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
55 },
56)]
57/// Create new traffic control rule.
58pub fn create_traffic_control(config: TrafficControlRule) -> Result<(), Error> {
59
60 let _lock = pbs_config::traffic_control::lock_config()?;
61
62 let (mut section_config, _digest) = pbs_config::traffic_control::config()?;
63
64 if section_config.sections.get(&config.name).is_some() {
65 bail!("traffic control rule '{}' already exists.", config.name);
66 }
67
68 section_config.set_data(&config.name, "rule", &config)?;
69
70 pbs_config::traffic_control::save_config(&section_config)?;
71
72 Ok(())
73}
74
75#[api(
76 input: {
77 properties: {
78 name: {
79 schema: TRAFFIC_CONTROL_ID_SCHEMA,
80 },
81 },
82 },
83 returns: { type: TrafficControlRule },
84 access: {
85 permission: &Permission::Privilege(&[], PRIV_SYS_AUDIT, false),
86 }
87)]
88/// Read traffic control configuration data.
89pub fn read_traffic_control(
90 name: String,
91 _info: &ApiMethod,
92 mut rpcenv: &mut dyn RpcEnvironment,
93) -> Result<TrafficControlRule, Error> {
94 let (config, digest) = pbs_config::traffic_control::config()?;
95 let data: TrafficControlRule = config.lookup("rule", &name)?;
25877d05 96 rpcenv["digest"] = hex::encode(&digest).into();
bfd12e87
DM
97 Ok(data)
98}
99
100#[api()]
101#[derive(Serialize, Deserialize)]
102#[allow(non_camel_case_types)]
4fe77c36 103#[serde(rename_all = "kebab-case")]
bfd12e87
DM
104/// Deletable property name
105pub enum DeletableProperty {
106 /// Delete the rate_in property.
107 rate_in,
108 /// Delete the burst_in property.
109 burst_in,
110 /// Delete the rate_out property.
111 rate_out,
112 /// Delete the burst_out property.
113 burst_out,
114 /// Delete the comment property.
115 comment,
116 /// Delete the timeframe property
117 timeframe,
118}
119
120// fixme: use TrafficControlUpdater
121#[api(
122 protected: true,
123 input: {
124 properties: {
125 name: {
126 schema: TRAFFIC_CONTROL_ID_SCHEMA,
127 },
128 update: {
129 type: TrafficControlRuleUpdater,
130 flatten: true,
131 },
132 delete: {
133 description: "List of properties to delete.",
134 type: Array,
135 optional: true,
136 items: {
137 type: DeletableProperty,
138 }
139 },
140 digest: {
141 optional: true,
142 schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
143 },
144 },
145 },
146 access: {
147 permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
148 },
149)]
150/// Update traffic control configuration.
151pub fn update_traffic_control(
152 name: String,
153 update: TrafficControlRuleUpdater,
154 delete: Option<Vec<DeletableProperty>>,
155 digest: Option<String>,
156) -> Result<(), Error> {
157
158 let _lock = pbs_config::traffic_control::lock_config()?;
159
160 let (mut config, expected_digest) = pbs_config::traffic_control::config()?;
161
162 if let Some(ref digest) = digest {
25877d05 163 let digest = <[u8; 32]>::from_hex(digest)?;
bfd12e87
DM
164 crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?;
165 }
166
167 let mut data: TrafficControlRule = config.lookup("rule", &name)?;
168
169 if let Some(delete) = delete {
170 for delete_prop in delete {
171 match delete_prop {
56472190
DM
172 DeletableProperty::rate_in => { data.limit.rate_in = None; },
173 DeletableProperty::rate_out => { data.limit.rate_out = None; },
174 DeletableProperty::burst_in => { data.limit.burst_in = None; },
175 DeletableProperty::burst_out => { data.limit.burst_out = None; },
bfd12e87
DM
176 DeletableProperty::comment => { data.comment = None; },
177 DeletableProperty::timeframe => { data.timeframe = None; },
178 }
179 }
180 }
181
182 if let Some(comment) = update.comment {
183 let comment = comment.trim().to_string();
184 if comment.is_empty() {
185 data.comment = None;
186 } else {
187 data.comment = Some(comment);
188 }
189 }
190
56472190
DM
191 if update.limit.rate_in.is_some() {
192 data.limit.rate_in = update.limit.rate_in;
193 }
194
195 if update.limit.rate_out.is_some() {
196 data.limit.rate_out = update.limit.rate_out;
197 }
198
199 if update.limit.burst_in.is_some() {
200 data.limit.burst_in = update.limit.burst_in;
201 }
202
203 if update.limit.burst_out.is_some() {
204 data.limit.burst_out = update.limit.burst_out;
205 }
bfd12e87 206
bfd12e87
DM
207 if let Some(network) = update.network { data.network = network; }
208 if update.timeframe.is_some() { data.timeframe = update.timeframe; }
209
210 config.set_data(&name, "rule", &data)?;
211
212 pbs_config::traffic_control::save_config(&config)?;
213
214 Ok(())
215}
216
217#[api(
218 protected: true,
219 input: {
220 properties: {
221 name: {
222 schema: TRAFFIC_CONTROL_ID_SCHEMA,
223 },
224 digest: {
225 optional: true,
226 schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
227 },
228 },
229 },
230 access: {
231 permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
232 },
233)]
234/// Remove a traffic control rule from the configuration file.
235pub fn delete_traffic_control(name: String, digest: Option<String>) -> Result<(), Error> {
236
237 let _lock = pbs_config::traffic_control::lock_config()?;
238
239 let (mut config, expected_digest) = pbs_config::traffic_control::config()?;
240
241 if let Some(ref digest) = digest {
25877d05 242 let digest = <[u8; 32]>::from_hex(digest)?;
bfd12e87
DM
243 crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?;
244 }
245
246 match config.sections.get(&name) {
247 Some(_) => { config.sections.remove(&name); },
248 None => bail!("traffic control rule '{}' does not exist.", name),
249 }
250
251 pbs_config::traffic_control::save_config(&config)?;
252
253 Ok(())
254}
255
256
257const ITEM_ROUTER: Router = Router::new()
258 .get(&API_METHOD_READ_TRAFFIC_CONTROL)
259 .put(&API_METHOD_UPDATE_TRAFFIC_CONTROL)
260 .delete(&API_METHOD_DELETE_TRAFFIC_CONTROL);
261
262pub const ROUTER: Router = Router::new()
263 .get(&API_METHOD_LIST_TRAFFIC_CONTROLS)
264 .post(&API_METHOD_CREATE_TRAFFIC_CONTROL)
265 .match_all("name", &ITEM_ROUTER);