Skip to content

Commit

Permalink
proxmoxve: Generate proper network unit for the DHCP case
Browse files Browse the repository at this point in the history
When DHCP is not specified in a systemd network unit, the default is
"no". For a "type: dhcp4" entry in the Proxmox VE network-config file
the systemd network unit should set DHCP=ipv4, and similar for "dhcp6".
  • Loading branch information
pothos authored and arcln committed Jun 5, 2024
1 parent 0b9830a commit c8dd952
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 2 deletions.
62 changes: 62 additions & 0 deletions src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub struct Interface {
pub priority: u8,
pub nameservers: Vec<IpAddr>,
pub ip_addresses: Vec<IpNetwork>,
// Optionally enable DHCP
pub dhcp: Option<DhcpSetting>,
pub routes: Vec<NetworkRoute>,
pub bond: Option<String>,
pub unmanaged: bool,
Expand Down Expand Up @@ -128,6 +130,31 @@ impl NetDevKind {
}
}

/// Optional use of DHCP.
#[allow(dead_code)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum DhcpSetting {
Both,
V4,
V6,
}

impl DhcpSetting {
/// Return DHCP setting according to `systemd.network`
///
/// See [systemd documentation](dhcp) for the full list.
///
/// dhcp: https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html#DHCP=
fn sd_dhcp_setting(&self) -> String {
let setting = match *self {
DhcpSetting::Both => "yes",
DhcpSetting::V4 => "ipv4",
DhcpSetting::V6 => "ipv6",
};
setting.to_string()
}
}

impl Interface {
/// Return a deterministic `systemd.network` unit name for this device.
pub fn sd_network_unit_name(&self) -> Result<String> {
Expand Down Expand Up @@ -158,6 +185,9 @@ impl Interface {

// [Network] section
writeln!(config, "\n[Network]").unwrap();
if let Some(dhcp) = &self.dhcp {
writeln!(config, "DHCP={}", dhcp.sd_dhcp_setting()).unwrap();
}
for ns in &self.nameservers {
writeln!(config, "DNS={ns}").unwrap()
}
Expand Down Expand Up @@ -246,6 +276,7 @@ mod tests {
priority: 20,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand All @@ -261,6 +292,7 @@ mod tests {
priority: 10,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand All @@ -276,6 +308,7 @@ mod tests {
priority: 20,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand All @@ -291,6 +324,7 @@ mod tests {
priority: 20,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand All @@ -306,6 +340,7 @@ mod tests {
priority: 20,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand All @@ -330,6 +365,7 @@ mod tests {
priority: 20,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand Down Expand Up @@ -387,6 +423,7 @@ mod tests {
Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 128).unwrap(),
),
],
dhcp: None,
routes: vec![NetworkRoute {
destination: IpNetwork::V4(
Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 1), 8).unwrap(),
Expand Down Expand Up @@ -428,6 +465,7 @@ Gateway=127.0.0.1
priority: 10,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand All @@ -447,6 +485,7 @@ Gateway=127.0.0.1
priority: 10,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: false,
Expand All @@ -470,6 +509,7 @@ RequiredForOnline=no
priority: 10,
nameservers: vec![],
ip_addresses: vec![],
dhcp: None,
routes: vec![],
bond: None,
unmanaged: true,
Expand All @@ -482,6 +522,28 @@ Name=*
[Link]
Unmanaged=yes
",
),
// test the DHCP setting
(
Interface {
name: Some("*".to_owned()),
mac_address: None,
path: None,
priority: 10,
nameservers: vec![],
ip_addresses: vec![],
dhcp: Some(DhcpSetting::V4),
routes: vec![],
bond: None,
unmanaged: false,
required_for_online: None,
},
"[Match]
Name=*
[Network]
DHCP=ipv4
",
),
];
Expand Down
1 change: 1 addition & 0 deletions src/providers/digitalocean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ impl DigitalOceanProvider {
mac_address: Some(mac),
nameservers: self.dns.nameservers.clone(),
ip_addresses: addrs,
dhcp: None,
routes,
bond: None,
name: None,
Expand Down
1 change: 1 addition & 0 deletions src/providers/ibmcloud_classic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ impl IBMClassicProvider {
priority: 10,
nameservers: nameservers.clone(),
ip_addresses: vec![ip_net],
dhcp: None,
routes,
bond: None,
unmanaged: false,
Expand Down
3 changes: 3 additions & 0 deletions src/providers/packet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ impl PacketProvider {
priority: 10,
nameservers: Vec::new(),
ip_addresses: Vec::new(),
dhcp: None,
routes: Vec::new(),
// the interface should be unmanaged if it doesn't have a bond
// section
Expand All @@ -241,6 +242,7 @@ impl PacketProvider {
path: None,
bond: None,
ip_addresses: Vec::new(),
dhcp: None,
routes: Vec::new(),
unmanaged: false,
required_for_online: Some("degraded-carrier".to_owned()),
Expand Down Expand Up @@ -334,6 +336,7 @@ impl PacketProvider {
bond: None,
nameservers: Vec::new(),
ip_addresses: Vec::new(),
dhcp: None,
routes: Vec::new(),
required_for_online: None,
};
Expand Down
10 changes: 9 additions & 1 deletion src/providers/proxmoxve/cloudconfig.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
network::{self, NetworkRoute},
network::{self, DhcpSetting, NetworkRoute},
providers::MetadataProvider,
};
use anyhow::Result;
Expand Down Expand Up @@ -207,6 +207,8 @@ impl ProxmoxVECloudNetworkConfigEntry {
ip_addresses: vec![],
// filled below
routes: vec![],
// filled below
dhcp: None,
// filled below because Option::try_map doesn't exist yet
mac_address: None,

Expand Down Expand Up @@ -257,6 +259,12 @@ impl ProxmoxVECloudNetworkConfigEntry {
}
}

if subnet.subnet_type == "dhcp" || subnet.subnet_type == "dhcp4" {
iface.dhcp = Some(DhcpSetting::V4)
}
if subnet.subnet_type == "dhcp6" {
iface.dhcp = Some(DhcpSetting::V6)
}
if subnet.subnet_type == "ipv6_slaac" {
warn!("subnet type \"ipv6_slaac\" not supported, ignoring");
}
Expand Down
5 changes: 4 additions & 1 deletion src/providers/proxmoxve/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::ProxmoxVECloudConfig;
use crate::{
network::{self, NetworkRoute},
network::{self, DhcpSetting, NetworkRoute},
providers::MetadataProvider,
};
use ipnetwork::IpNetwork;
Expand Down Expand Up @@ -64,6 +64,7 @@ fn test_network_dhcp() {
mac_address: Some(MacAddr::from_str("01:23:45:67:89:00").unwrap()),
path: None,
priority: 20,
dhcp: Some(DhcpSetting::V4),
nameservers: vec![
IpAddr::from_str("1.1.1.1").unwrap(),
IpAddr::from_str("8.8.8.8").unwrap()
Expand Down Expand Up @@ -98,6 +99,7 @@ fn test_network_static() {
IpNetwork::from_str("192.168.1.1/24").unwrap(),
IpNetwork::from_str("2001:0db8:85a3:0000:0000:8a2e:0370:0/24").unwrap(),
],
dhcp: None,
routes: vec![
NetworkRoute {
destination: IpNetwork::from_str("0.0.0.0/0").unwrap(),
Expand All @@ -123,6 +125,7 @@ fn test_network_static() {
IpNetwork::from_str("192.168.42.1/24").unwrap(),
IpNetwork::from_str("2001:0db8:85a3:0000:0000:8a2e:4242:0/24").unwrap(),
],
dhcp: None,
routes: vec![
NetworkRoute {
destination: IpNetwork::from_str("0.0.0.0/0").unwrap(),
Expand Down

0 comments on commit c8dd952

Please sign in to comment.