Add basic NAT structures

This commit is contained in:
2024-01-08 21:03:39 +01:00
parent 80ecb3c5d2
commit 672e866897
9 changed files with 190 additions and 30 deletions

View File

@ -1,6 +1,8 @@
use crate::libvirt_lib_structures::network::*;
use crate::libvirt_lib_structures::XMLUuid;
use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
use crate::nat::nat_definition::Nat;
use crate::nat::nat_lib;
use crate::utils::net_utils::{extract_ipv4, extract_ipv6};
use ipnetwork::{Ipv4Network, Ipv6Network};
use lazy_regex::regex;
@ -21,57 +23,68 @@ pub struct DHCPv4HostReservation {
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct IPv4DHCPConfig {
start: Ipv4Addr,
end: Ipv4Addr,
hosts: Vec<DHCPv4HostReservation>,
pub start: Ipv4Addr,
pub end: Ipv4Addr,
pub hosts: Vec<DHCPv4HostReservation>,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct IPV4Config {
bridge_address: Ipv4Addr,
prefix: u32,
dhcp: Option<IPv4DHCPConfig>,
pub bridge_address: Ipv4Addr,
pub prefix: u32,
pub dhcp: Option<IPv4DHCPConfig>,
pub nat: Option<Vec<Nat<Ipv4Addr>>>,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct DHCPv6HostReservation {
name: String,
ip: Ipv6Addr,
pub name: String,
pub ip: Ipv6Addr,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct IPv6DHCPConfig {
start: Ipv6Addr,
end: Ipv6Addr,
hosts: Vec<DHCPv6HostReservation>,
pub start: Ipv6Addr,
pub end: Ipv6Addr,
pub hosts: Vec<DHCPv6HostReservation>,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct IPV6Config {
bridge_address: Ipv6Addr,
prefix: u32,
dhcp: Option<IPv6DHCPConfig>,
pub bridge_address: Ipv6Addr,
pub prefix: u32,
pub dhcp: Option<IPv6DHCPConfig>,
pub nat: Option<Vec<Nat<Ipv6Addr>>>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkName(pub String);
impl NetworkName {
pub fn is_valid(&self) -> bool {
regex!("^[a-zA-Z0-9]+$").is_match(&self.0)
}
}
/// Network configuration
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct NetworkInfo {
pub name: String,
pub name: NetworkName,
pub uuid: Option<XMLUuid>,
title: Option<String>,
description: Option<String>,
forward_mode: NetworkForwardMode,
device: Option<String>,
bridge_name: Option<String>,
dns_server: Option<Ipv4Addr>,
domain: Option<String>,
ip_v4: Option<IPV4Config>,
ip_v6: Option<IPV6Config>,
pub title: Option<String>,
pub description: Option<String>,
pub forward_mode: NetworkForwardMode,
pub device: Option<String>,
pub bridge_name: Option<String>,
pub dns_server: Option<Ipv4Addr>,
pub domain: Option<String>,
pub ip_v4: Option<IPV4Config>,
pub ip_v6: Option<IPV6Config>,
}
impl NetworkInfo {
pub fn as_virt_network(&self) -> anyhow::Result<NetworkXML> {
if !regex!("^[a-zA-Z0-9]+$").is_match(&self.name) {
if !self.name.is_valid() {
return Err(StructureExtraction("network name is invalid!").into());
}
@ -160,7 +173,7 @@ impl NetworkInfo {
}
Ok(NetworkXML {
name: self.name.to_string(),
name: self.name.0.to_string(),
uuid: self.uuid,
title: self.title.clone(),
description: self.description.clone(),
@ -183,8 +196,12 @@ impl NetworkInfo {
}
pub fn from_xml(xml: NetworkXML) -> anyhow::Result<Self> {
let name = NetworkName(xml.name);
let nat = nat_lib::load_nat_def(&name)?;
Ok(Self {
name: xml.name,
name,
uuid: xml.uuid,
title: xml.title,
description: xml.description,
@ -227,6 +244,7 @@ impl NetworkInfo {
})
.collect(),
}),
nat: nat.ipv4,
}),
ip_v6: xml
.ips
@ -252,7 +270,25 @@ impl NetworkInfo {
})
.collect(),
}),
nat: nat.ipv6,
}),
})
}
/// Check if at least one NAT definition was specified on this interface
pub fn has_nat_def(&self) -> bool {
if let Some(ipv4) = &self.ip_v4 {
if ipv4.nat.is_some() {
return true;
}
}
if let Some(ipv6) = &self.ip_v6 {
if ipv6.nat.is_some() {
return true;
}
}
false
}
}