src/api2/config/network.rs: start network configuration api
This commit is contained in:
parent
904e988667
commit
ca0e534796
|
@ -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),
|
||||
];
|
||||
|
||||
|
|
|
@ -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);
|
|
@ -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())
|
||||
|
|
|
@ -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,
|
||||
#[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>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue