src/api2/config/network.rs: start network configuration api

This commit is contained in:
Dietmar Maurer 2020-04-21 14:28:26 +02:00
parent 904e988667
commit ca0e534796
4 changed files with 125 additions and 4 deletions

View File

@ -3,9 +3,11 @@ use proxmox::list_subdirs_api_method;
pub mod datastore;
pub mod remote;
pub mod network;
const SUBDIRS: SubdirMap = &[
("datastore", &datastore::ROUTER),
("network", &network::ROUTER),
("remote", &remote::ROUTER),
];

View File

@ -0,0 +1,47 @@
use anyhow::{Error};
use serde_json::{Value, to_value};
use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
//use crate::api2::types::*;
use crate::config::network;
use crate::config::acl::{PRIV_SYS_AUDIT};
#[api(
input: {
properties: {},
},
returns: {
description: "List network devices (with config digest).",
type: Array,
items: {
type: network::Interface,
},
},
access: {
permission: &Permission::Privilege(&[], PRIV_SYS_AUDIT, false),
},
)]
/// List all datastores
pub fn list_network_devices(
_param: Value,
_info: &ApiMethod,
_rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
let (config, digest) = network::config()?;
let digest = proxmox::tools::digest_to_hex(&digest);
let mut list = Vec::new();
for interface in config.interfaces.values() {
let mut item: Value = to_value(interface)?;
item["digest"] = digest.clone().into();
list.push(item);
}
Ok(list.into())
}
pub const ROUTER: Router = Router::new()
.get(&API_METHOD_LIST_NETWORK_DEVICES);

View File

@ -233,6 +233,14 @@ fn acl_commands() -> CommandLineInterface {
cmd_def.into()
}
fn network_commands() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
.insert("list", CliCommand::new(&api2::config::network::API_METHOD_LIST_NETWORK_DEVICES));
cmd_def.into()
}
fn datastore_commands() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
@ -603,6 +611,7 @@ fn main() {
let cmd_def = CliCommandMap::new()
.insert("acl", acl_commands())
.insert("datastore", datastore_commands())
.insert("network", network_commands())
.insert("user", user_commands())
.insert("remote", remote_commands())
.insert("garbage-collection", garbage_collection_commands())

View File

@ -2,8 +2,10 @@ use std::io::{Write};
use std::collections::{HashSet, HashMap};
use anyhow::{Error, bail};
use serde::{Serialize, Deserialize};
use proxmox::tools::{fs::replace_file, fs::CreateOptions};
use proxmox::api::api;
mod helper;
pub use helper::*;
@ -14,29 +16,90 @@ pub use lexer::*;
mod parser;
pub use parser::*;
#[derive(Debug, Copy, Clone, PartialEq)]
#[api()]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
/// Interface configuration method
pub enum ConfigMethod {
/// Configuration is done manually using other tools
Manual,
/// Define interfaces with statically allocated addresses.
Static,
/// Obtain an address via DHCP
DHCP,
/// Define the loopback interface.
Loopback,
}
#[derive(Debug)]
#[api(
properties: {
name: {
type: String,
min_length: 1,
max_length: libc::IFNAMSIZ-1,
},
method_v4: {
type: ConfigMethod,
optional: true,
},
method_v6: {
type: ConfigMethod,
optional: true,
},
options_v4: {
description: "Option list (inet)",
type: Array,
items: {
description: "Optional attribute.",
type: String,
},
},
options_v6: {
description: "Option list (inet6)",
type: Array,
items: {
description: "Optional attribute.",
type: String,
},
},
}
)]
#[derive(Debug, Serialize, Deserialize)]
/// Network Interface configuration
pub struct Interface {
/// Autostart interface
pub autostart: bool,
/// Interface is a physical network device
pub exists: bool,
/// Interface is active (UP)
pub active: bool,
/// Interface name
pub name: String,
pub method_v4: Option<ConfigMethod>,
#[serde(skip_serializing_if="Option::is_none")]
pub method_v4: Option<ConfigMethod>,
#[serde(skip_serializing_if="Option::is_none")]
pub method_v6: Option<ConfigMethod>,
#[serde(skip_serializing_if="Option::is_none")]
/// IPv4 address
pub address_v4: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
/// IPv4 gateway
pub gateway_v4: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
/// IPv4 netmask
pub netmask_v4: Option<u8>,
#[serde(skip_serializing_if="Option::is_none")]
/// IPv6 address
pub address_v6: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
/// IPv6 gateway
pub gateway_v6: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
/// IPv6 netmask
pub netmask_v6: Option<u8>,
#[serde(skip_serializing_if="Vec::is_empty")]
pub options_v4: Vec<String>,
#[serde(skip_serializing_if="Vec::is_empty")]
pub options_v6: Vec<String>,
}
@ -231,7 +294,7 @@ enum NetworkOrderEntry {
#[derive(Debug)]
pub struct NetworkConfig {
interfaces: HashMap<String, Interface>,
pub interfaces: HashMap<String, Interface>,
order: Vec<NetworkOrderEntry>,
}