src/api2/config/network.rs: start network configuration api
This commit is contained in:
		@ -3,9 +3,11 @@ use proxmox::list_subdirs_api_method;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub mod datastore;
 | 
					pub mod datastore;
 | 
				
			||||||
pub mod remote;
 | 
					pub mod remote;
 | 
				
			||||||
 | 
					pub mod network;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SUBDIRS: SubdirMap = &[
 | 
					const SUBDIRS: SubdirMap = &[
 | 
				
			||||||
    ("datastore", &datastore::ROUTER),
 | 
					    ("datastore", &datastore::ROUTER),
 | 
				
			||||||
 | 
					    ("network", &network::ROUTER),
 | 
				
			||||||
    ("remote", &remote::ROUTER),
 | 
					    ("remote", &remote::ROUTER),
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										47
									
								
								src/api2/config/network.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/api2/config/network.rs
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
@ -233,6 +233,14 @@ fn acl_commands() -> CommandLineInterface {
 | 
				
			|||||||
    cmd_def.into()
 | 
					    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 {
 | 
					fn datastore_commands() -> CommandLineInterface {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let cmd_def = CliCommandMap::new()
 | 
					    let cmd_def = CliCommandMap::new()
 | 
				
			||||||
@ -603,6 +611,7 @@ fn main() {
 | 
				
			|||||||
    let cmd_def = CliCommandMap::new()
 | 
					    let cmd_def = CliCommandMap::new()
 | 
				
			||||||
        .insert("acl", acl_commands())
 | 
					        .insert("acl", acl_commands())
 | 
				
			||||||
        .insert("datastore", datastore_commands())
 | 
					        .insert("datastore", datastore_commands())
 | 
				
			||||||
 | 
					        .insert("network", network_commands())
 | 
				
			||||||
        .insert("user", user_commands())
 | 
					        .insert("user", user_commands())
 | 
				
			||||||
        .insert("remote", remote_commands())
 | 
					        .insert("remote", remote_commands())
 | 
				
			||||||
        .insert("garbage-collection", garbage_collection_commands())
 | 
					        .insert("garbage-collection", garbage_collection_commands())
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,10 @@ use std::io::{Write};
 | 
				
			|||||||
use std::collections::{HashSet, HashMap};
 | 
					use std::collections::{HashSet, HashMap};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use anyhow::{Error, bail};
 | 
					use anyhow::{Error, bail};
 | 
				
			||||||
 | 
					use serde::{Serialize, Deserialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use proxmox::tools::{fs::replace_file, fs::CreateOptions};
 | 
					use proxmox::tools::{fs::replace_file, fs::CreateOptions};
 | 
				
			||||||
 | 
					use proxmox::api::api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod helper;
 | 
					mod helper;
 | 
				
			||||||
pub use helper::*;
 | 
					pub use helper::*;
 | 
				
			||||||
@ -14,29 +16,90 @@ pub use lexer::*;
 | 
				
			|||||||
mod parser;
 | 
					mod parser;
 | 
				
			||||||
pub use 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 {
 | 
					pub enum ConfigMethod {
 | 
				
			||||||
 | 
					    /// Configuration is done manually using other tools
 | 
				
			||||||
    Manual,
 | 
					    Manual,
 | 
				
			||||||
 | 
					    /// Define interfaces with statically allocated addresses.
 | 
				
			||||||
    Static,
 | 
					    Static,
 | 
				
			||||||
 | 
					    /// Obtain an address via DHCP
 | 
				
			||||||
    DHCP,
 | 
					    DHCP,
 | 
				
			||||||
 | 
					    /// Define the loopback interface.
 | 
				
			||||||
    Loopback,
 | 
					    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 {
 | 
					pub struct Interface {
 | 
				
			||||||
 | 
					    /// Autostart interface
 | 
				
			||||||
    pub autostart: bool,
 | 
					    pub autostart: bool,
 | 
				
			||||||
 | 
					    /// Interface is a physical network device
 | 
				
			||||||
    pub exists: bool,
 | 
					    pub exists: bool,
 | 
				
			||||||
 | 
					    /// Interface is active (UP)
 | 
				
			||||||
    pub active: bool,
 | 
					    pub active: bool,
 | 
				
			||||||
 | 
					    /// Interface name
 | 
				
			||||||
    pub name: String,
 | 
					    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>,
 | 
					    pub method_v6: Option<ConfigMethod>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Option::is_none")]
 | 
				
			||||||
 | 
					    /// IPv4 address
 | 
				
			||||||
    pub address_v4: Option<String>,
 | 
					    pub address_v4: Option<String>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Option::is_none")]
 | 
				
			||||||
 | 
					    /// IPv4 gateway
 | 
				
			||||||
    pub gateway_v4: Option<String>,
 | 
					    pub gateway_v4: Option<String>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Option::is_none")]
 | 
				
			||||||
 | 
					    /// IPv4 netmask
 | 
				
			||||||
    pub netmask_v4: Option<u8>,
 | 
					    pub netmask_v4: Option<u8>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Option::is_none")]
 | 
				
			||||||
 | 
					    /// IPv6 address
 | 
				
			||||||
    pub address_v6: Option<String>,
 | 
					    pub address_v6: Option<String>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Option::is_none")]
 | 
				
			||||||
 | 
					    /// IPv6 gateway
 | 
				
			||||||
    pub gateway_v6: Option<String>,
 | 
					    pub gateway_v6: Option<String>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Option::is_none")]
 | 
				
			||||||
 | 
					    /// IPv6 netmask
 | 
				
			||||||
    pub netmask_v6: Option<u8>,
 | 
					    pub netmask_v6: Option<u8>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Vec::is_empty")]
 | 
				
			||||||
    pub options_v4: Vec<String>,
 | 
					    pub options_v4: Vec<String>,
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if="Vec::is_empty")]
 | 
				
			||||||
    pub options_v6: Vec<String>,
 | 
					    pub options_v6: Vec<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -231,7 +294,7 @@ enum NetworkOrderEntry {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct NetworkConfig {
 | 
					pub struct NetworkConfig {
 | 
				
			||||||
    interfaces: HashMap<String, Interface>,
 | 
					    pub interfaces: HashMap<String, Interface>,
 | 
				
			||||||
    order: Vec<NetworkOrderEntry>,
 | 
					    order: Vec<NetworkOrderEntry>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user