]> git.proxmox.com Git - proxmox-backup.git/blame - pbs-api-types/src/network.rs
fix non-camel-case enums
[proxmox-backup.git] / pbs-api-types / src / network.rs
CommitLineData
a2055c38
WB
1use std::fmt;
2
6f422880
DM
3use serde::{Deserialize, Serialize};
4
6ef1b649 5use proxmox_schema::*;
6f422880
DM
6
7use crate::{
b22d785c 8 CIDR_FORMAT, CIDR_V4_FORMAT, CIDR_V6_FORMAT, IP_FORMAT, IP_V4_FORMAT, IP_V6_FORMAT,
6f422880 9 PROXMOX_SAFE_ID_REGEX,
6f422880
DM
10};
11
12pub const NETWORK_INTERFACE_FORMAT: ApiStringFormat =
13 ApiStringFormat::Pattern(&PROXMOX_SAFE_ID_REGEX);
14
b22d785c 15pub const IP_V4_SCHEMA: Schema = StringSchema::new("IPv4 address.")
6f422880
DM
16 .format(&IP_V4_FORMAT)
17 .max_length(15)
18 .schema();
19
b22d785c 20pub const IP_V6_SCHEMA: Schema = StringSchema::new("IPv6 address.")
6f422880
DM
21 .format(&IP_V6_FORMAT)
22 .max_length(39)
23 .schema();
24
b22d785c 25pub const IP_SCHEMA: Schema = StringSchema::new("IP (IPv4 or IPv6) address.")
6f422880
DM
26 .format(&IP_FORMAT)
27 .max_length(39)
28 .schema();
29
b22d785c 30pub const CIDR_V4_SCHEMA: Schema = StringSchema::new("IPv4 address with netmask (CIDR notation).")
6f422880
DM
31 .format(&CIDR_V4_FORMAT)
32 .max_length(18)
33 .schema();
34
b22d785c 35pub const CIDR_V6_SCHEMA: Schema = StringSchema::new("IPv6 address with netmask (CIDR notation).")
6f422880
DM
36 .format(&CIDR_V6_FORMAT)
37 .max_length(43)
38 .schema();
39
40pub const CIDR_SCHEMA: Schema =
41 StringSchema::new("IP address (IPv4 or IPv6) with netmask (CIDR notation).")
b22d785c
TL
42 .format(&CIDR_FORMAT)
43 .max_length(43)
44 .schema();
6f422880
DM
45
46#[api()]
f680e72f 47#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
6f422880
DM
48#[serde(rename_all = "lowercase")]
49/// Interface configuration method
50pub enum NetworkConfigMethod {
51 /// Configuration is done manually using other tools
52 Manual,
53 /// Define interfaces with statically allocated addresses.
54 Static,
55 /// Obtain an address via DHCP
56 DHCP,
57 /// Define the loopback interface.
58 Loopback,
59}
60
61#[api()]
f680e72f 62#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
6f422880 63#[serde(rename_all = "kebab-case")]
6f422880
DM
64#[repr(u8)]
65/// Linux Bond Mode
66pub enum LinuxBondMode {
67 /// Round-robin policy
a2055c38 68 BalanceRr = 0,
6f422880 69 /// Active-backup policy
a2055c38 70 ActiveBackup = 1,
6f422880 71 /// XOR policy
a2055c38 72 BalanceXor = 2,
6f422880 73 /// Broadcast policy
a2055c38 74 Broadcast = 3,
6f422880
DM
75 /// IEEE 802.3ad Dynamic link aggregation
76 #[serde(rename = "802.3ad")]
a2055c38 77 Ieee802_3ad = 4,
6f422880 78 /// Adaptive transmit load balancing
a2055c38 79 BalanceTlb = 5,
6f422880 80 /// Adaptive load balancing
a2055c38
WB
81 BalanceAlb = 6,
82}
83
84impl fmt::Display for LinuxBondMode {
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 f.write_str(match self {
87 LinuxBondMode::BalanceRr => "balance-rr",
88 LinuxBondMode::ActiveBackup => "active-backup",
89 LinuxBondMode::BalanceXor => "balance-xor",
90 LinuxBondMode::Broadcast => "broadcast",
91 LinuxBondMode::Ieee802_3ad => "802.3ad",
92 LinuxBondMode::BalanceTlb => "balance-tlb",
93 LinuxBondMode::BalanceAlb => "balance-alb",
94 })
95 }
6f422880
DM
96}
97
98#[api()]
f680e72f 99#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
6f422880 100#[serde(rename_all = "kebab-case")]
6f422880
DM
101#[repr(u8)]
102/// Bond Transmit Hash Policy for LACP (802.3ad)
103pub enum BondXmitHashPolicy {
104 /// Layer 2
a2055c38 105 Layer2 = 0,
6f422880
DM
106 /// Layer 2+3
107 #[serde(rename = "layer2+3")]
a2055c38 108 Layer2_3 = 1,
6f422880
DM
109 /// Layer 3+4
110 #[serde(rename = "layer3+4")]
a2055c38
WB
111 Layer3_4 = 2,
112}
113
114impl fmt::Display for BondXmitHashPolicy {
115 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116 f.write_str(match self {
117 BondXmitHashPolicy::Layer2 => "layer2",
118 BondXmitHashPolicy::Layer2_3 => "layer2+3",
119 BondXmitHashPolicy::Layer3_4 => "layer3+4",
120 })
121 }
6f422880
DM
122}
123
124#[api()]
f680e72f 125#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
6f422880
DM
126#[serde(rename_all = "lowercase")]
127/// Network interface type
128pub enum NetworkInterfaceType {
129 /// Loopback
130 Loopback,
131 /// Physical Ethernet device
132 Eth,
133 /// Linux Bridge
134 Bridge,
135 /// Linux Bond
136 Bond,
137 /// Linux VLAN (eth.10)
138 Vlan,
139 /// Interface Alias (eth:1)
140 Alias,
141 /// Unknown interface type
142 Unknown,
143}
144
145pub const NETWORK_INTERFACE_NAME_SCHEMA: Schema = StringSchema::new("Network interface name.")
146 .format(&NETWORK_INTERFACE_FORMAT)
147 .min_length(1)
f7fde5c8 148 .max_length(15) // libc::IFNAMSIZ-1
6f422880
DM
149 .schema();
150
b22d785c
TL
151pub const NETWORK_INTERFACE_ARRAY_SCHEMA: Schema =
152 ArraySchema::new("Network interface list.", &NETWORK_INTERFACE_NAME_SCHEMA).schema();
6f422880 153
b22d785c
TL
154pub const NETWORK_INTERFACE_LIST_SCHEMA: Schema =
155 StringSchema::new("A list of network devices, comma separated.")
156 .format(&ApiStringFormat::PropertyString(
157 &NETWORK_INTERFACE_ARRAY_SCHEMA,
158 ))
159 .schema();
6f422880
DM
160
161#[api(
162 properties: {
163 name: {
164 schema: NETWORK_INTERFACE_NAME_SCHEMA,
165 },
166 "type": {
167 type: NetworkInterfaceType,
168 },
169 method: {
170 type: NetworkConfigMethod,
171 optional: true,
172 },
173 method6: {
174 type: NetworkConfigMethod,
175 optional: true,
176 },
177 cidr: {
178 schema: CIDR_V4_SCHEMA,
179 optional: true,
180 },
181 cidr6: {
182 schema: CIDR_V6_SCHEMA,
183 optional: true,
184 },
185 gateway: {
186 schema: IP_V4_SCHEMA,
187 optional: true,
188 },
189 gateway6: {
190 schema: IP_V6_SCHEMA,
191 optional: true,
192 },
193 options: {
194 description: "Option list (inet)",
195 type: Array,
196 items: {
197 description: "Optional attribute line.",
198 type: String,
199 },
200 },
201 options6: {
202 description: "Option list (inet6)",
203 type: Array,
204 items: {
205 description: "Optional attribute line.",
206 type: String,
207 },
208 },
209 comments: {
210 description: "Comments (inet, may span multiple lines)",
211 type: String,
212 optional: true,
213 },
214 comments6: {
215 description: "Comments (inet6, may span multiple lines)",
216 type: String,
217 optional: true,
218 },
219 bridge_ports: {
220 schema: NETWORK_INTERFACE_ARRAY_SCHEMA,
221 optional: true,
222 },
223 slaves: {
224 schema: NETWORK_INTERFACE_ARRAY_SCHEMA,
225 optional: true,
226 },
227 bond_mode: {
228 type: LinuxBondMode,
229 optional: true,
230 },
231 "bond-primary": {
232 schema: NETWORK_INTERFACE_NAME_SCHEMA,
233 optional: true,
234 },
235 bond_xmit_hash_policy: {
236 type: BondXmitHashPolicy,
237 optional: true,
238 },
239 }
240)]
241#[derive(Debug, Serialize, Deserialize)]
242/// Network Interface configuration
243pub struct Interface {
244 /// Autostart interface
245 #[serde(rename = "autostart")]
246 pub autostart: bool,
247 /// Interface is active (UP)
248 pub active: bool,
249 /// Interface name
250 pub name: String,
251 /// Interface type
252 #[serde(rename = "type")]
253 pub interface_type: NetworkInterfaceType,
b22d785c 254 #[serde(skip_serializing_if = "Option::is_none")]
6f422880 255 pub method: Option<NetworkConfigMethod>,
b22d785c 256 #[serde(skip_serializing_if = "Option::is_none")]
6f422880 257 pub method6: Option<NetworkConfigMethod>,
b22d785c 258 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
259 /// IPv4 address with netmask
260 pub cidr: Option<String>,
b22d785c 261 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
262 /// IPv4 gateway
263 pub gateway: Option<String>,
b22d785c 264 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
265 /// IPv6 address with netmask
266 pub cidr6: Option<String>,
b22d785c 267 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
268 /// IPv6 gateway
269 pub gateway6: Option<String>,
270
b22d785c 271 #[serde(skip_serializing_if = "Vec::is_empty")]
6f422880 272 pub options: Vec<String>,
b22d785c 273 #[serde(skip_serializing_if = "Vec::is_empty")]
6f422880
DM
274 pub options6: Vec<String>,
275
b22d785c 276 #[serde(skip_serializing_if = "Option::is_none")]
6f422880 277 pub comments: Option<String>,
b22d785c 278 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
279 pub comments6: Option<String>,
280
b22d785c 281 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
282 /// Maximum Transmission Unit
283 pub mtu: Option<u64>,
284
b22d785c 285 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
286 pub bridge_ports: Option<Vec<String>>,
287 /// Enable bridge vlan support.
b22d785c 288 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
289 pub bridge_vlan_aware: Option<bool>,
290
b22d785c 291 #[serde(skip_serializing_if = "Option::is_none")]
6f422880 292 pub slaves: Option<Vec<String>>,
b22d785c 293 #[serde(skip_serializing_if = "Option::is_none")]
6f422880 294 pub bond_mode: Option<LinuxBondMode>,
b22d785c 295 #[serde(skip_serializing_if = "Option::is_none")]
6f422880
DM
296 #[serde(rename = "bond-primary")]
297 pub bond_primary: Option<String>,
298 pub bond_xmit_hash_policy: Option<BondXmitHashPolicy>,
299}
300
301impl Interface {
302 pub fn new(name: String) -> Self {
b22d785c 303 Self {
6f422880
DM
304 name,
305 interface_type: NetworkInterfaceType::Unknown,
306 autostart: false,
307 active: false,
308 method: None,
309 method6: None,
310 cidr: None,
311 gateway: None,
312 cidr6: None,
313 gateway6: None,
314 options: Vec::new(),
315 options6: Vec::new(),
316 comments: None,
317 comments6: None,
318 mtu: None,
319 bridge_ports: None,
320 bridge_vlan_aware: None,
321 slaves: None,
322 bond_mode: None,
323 bond_primary: None,
324 bond_xmit_hash_policy: None,
325 }
326 }
327}