]> git.proxmox.com Git - proxmox-backup.git/blame - src/bin/proxmox_backup_manager/network.rs
update to first proxmox crate split
[proxmox-backup.git] / src / bin / proxmox_backup_manager / network.rs
CommitLineData
a35a211d
DM
1use anyhow::Error;
2use serde_json::Value;
3
6ef1b649
WB
4use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
5use proxmox_schema::api;
a35a211d 6
a35a211d
DM
7use proxmox_backup::api2;
8
9#[api(
10 input: {
11 properties: {
12 "output-format": {
13 schema: OUTPUT_FORMAT,
14 optional: true,
15 },
16 }
17 }
18)]
19/// Network device list.
20fn list_network_devices(mut param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> {
21
22 let output_format = get_output_format(&param);
23
24 param["node"] = "localhost".into();
25
26 let info = &api2::node::network::API_METHOD_LIST_NETWORK_DEVICES;
27 let mut data = match info.handler {
28 ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?,
29 _ => unreachable!(),
30 };
31
32 if let Value::String(ref diff) = rpcenv["changes"] {
33 if output_format == "text" {
34 eprintln!("pending changes:\n{}\n", diff);
35 }
36 }
37
38 fn render_address(_value: &Value, record: &Value) -> Result<String, Error> {
39 let mut text = String::new();
40
41 if let Some(cidr) = record["cidr"].as_str() {
42 text.push_str(cidr);
43 }
44 if let Some(cidr) = record["cidr6"].as_str() {
45 if !text.is_empty() { text.push('\n'); }
46 text.push_str(cidr);
47 }
48
49 Ok(text)
50 }
51
52 fn render_ports(_value: &Value, record: &Value) -> Result<String, Error> {
53 let mut text = String::new();
54
55 if let Some(ports) = record["bridge_ports"].as_array() {
56 let list: Vec<&str> = ports.iter().filter_map(|v| v.as_str()).collect();
57 text.push_str(&list.join(" "));
58 }
59 if let Some(slaves) = record["slaves"].as_array() {
60 let list: Vec<&str> = slaves.iter().filter_map(|v| v.as_str()).collect();
61 text.push_str(&list.join(" "));
62 }
63
64 Ok(text)
65 }
66
67 fn render_gateway(_value: &Value, record: &Value) -> Result<String, Error> {
68 let mut text = String::new();
69
70 if let Some(gateway) = record["gateway"].as_str() {
71 text.push_str(gateway);
72 }
73 if let Some(gateway) = record["gateway6"].as_str() {
74 if !text.is_empty() { text.push('\n'); }
75 text.push_str(gateway);
76 }
77
78 Ok(text)
79 }
80
81 let options = default_table_format_options()
82 .column(ColumnConfig::new("name"))
83 .column(ColumnConfig::new("type").header("type"))
84 .column(ColumnConfig::new("autostart"))
85 .column(ColumnConfig::new("method"))
86 .column(ColumnConfig::new("method6"))
87 .column(ColumnConfig::new("cidr").header("address").renderer(render_address))
88 .column(ColumnConfig::new("gateway").header("gateway").renderer(render_gateway))
89 .column(ColumnConfig::new("bridge_ports").header("ports/slaves").renderer(render_ports));
90
b2362a12 91 format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
a35a211d
DM
92
93 Ok(Value::Null)
94}
95
96#[api()]
97/// Show pending configuration changes (diff)
98fn pending_network_changes(mut param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> {
99 param["node"] = "localhost".into();
100
101 let info = &api2::node::network::API_METHOD_LIST_NETWORK_DEVICES;
102 let _data = match info.handler {
103 ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?,
104 _ => unreachable!(),
105 };
106
107 if let Value::String(ref diff) = rpcenv["changes"] {
108 println!("{}", diff);
109 }
110
111 Ok(Value::Null)
112}
113
114pub fn network_commands() -> CommandLineInterface {
115
116 let cmd_def = CliCommandMap::new()
117 .insert(
118 "list",
119 CliCommand::new(&API_METHOD_LIST_NETWORK_DEVICES)
120 )
121 .insert(
122 "changes",
123 CliCommand::new(&API_METHOD_PENDING_NETWORK_CHANGES)
124 )
125 .insert(
126 "create",
127 CliCommand::new(&api2::node::network::API_METHOD_CREATE_INTERFACE)
128 .fixed_param("node", String::from("localhost"))
129 .arg_param(&["iface"])
6f422880
DM
130 .completion_cb("iface", pbs_config::network::complete_interface_name)
131 .completion_cb("bridge_ports", pbs_config::network::complete_port_list)
132 .completion_cb("slaves", pbs_config::network::complete_port_list)
a35a211d
DM
133 )
134 .insert(
135 "update",
136 CliCommand::new(&api2::node::network::API_METHOD_UPDATE_INTERFACE)
137 .fixed_param("node", String::from("localhost"))
138 .arg_param(&["iface"])
6f422880
DM
139 .completion_cb("iface", pbs_config::network::complete_interface_name)
140 .completion_cb("bridge_ports", pbs_config::network::complete_port_list)
141 .completion_cb("slaves", pbs_config::network::complete_port_list)
a35a211d
DM
142 )
143 .insert(
144 "remove",
145 CliCommand::new(&api2::node::network::API_METHOD_DELETE_INTERFACE)
146 .fixed_param("node", String::from("localhost"))
147 .arg_param(&["iface"])
6f422880 148 .completion_cb("iface", pbs_config::network::complete_interface_name)
a35a211d
DM
149 )
150 .insert(
151 "revert",
152 CliCommand::new(&api2::node::network::API_METHOD_REVERT_NETWORK_CONFIG)
153 .fixed_param("node", String::from("localhost"))
154 )
155 .insert(
156 "reload",
157 CliCommand::new(&api2::node::network::API_METHOD_RELOAD_NETWORK_CONFIG)
158 .fixed_param("node", String::from("localhost"))
159 );
160
161 cmd_def.into()
162}