[pve-devel] [RFC pve-network 1/9] define dhcpplugin in zone

Alexandre Derumier aderumier at odiso.com
Mon Nov 13 11:04:06 CET 2023


simple: zone1
        ipam pve
        dhcp dnsmasq

simple: zone2
        ipam pve
        dhcp dnsmasq

This generate 1 dhcp by zone/vrf.

Don't use dhcp.cfg anymore
It's reuse node filtering from zone.

same subnets in 2 differents zones can't use
same dhcp server

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 src/PVE/API2/Network/SDN/Zones.pm         |  1 +
 src/PVE/Network/SDN.pm                    |  4 +-
 src/PVE/Network/SDN/Dhcp.pm               | 91 +++++++----------------
 src/PVE/Network/SDN/Dhcp/Dnsmasq.pm       | 32 ++++----
 src/PVE/Network/SDN/Dhcp/Plugin.pm        | 28 ++-----
 src/PVE/Network/SDN/SubnetPlugin.pm       |  4 -
 src/PVE/Network/SDN/Zones/SimplePlugin.pm |  7 +-
 7 files changed, 54 insertions(+), 113 deletions(-)

diff --git a/src/PVE/API2/Network/SDN/Zones.pm b/src/PVE/API2/Network/SDN/Zones.pm
index 4c8b7e1..1c3356e 100644
--- a/src/PVE/API2/Network/SDN/Zones.pm
+++ b/src/PVE/API2/Network/SDN/Zones.pm
@@ -99,6 +99,7 @@ __PACKAGE__->register_method ({
 			    reversedns => { type => 'string', optional => 1},
 			    dnszone => { type => 'string', optional => 1},
 			    ipam => { type => 'string', optional => 1},
+			    dhcp => { type => 'string', optional => 1},
 			    pending => { optional => 1},
 			    state => { type => 'string', optional => 1},
 			    nodes => { type => 'string', optional => 1},
diff --git a/src/PVE/Network/SDN.pm b/src/PVE/Network/SDN.pm
index 5c059bc..c306527 100644
--- a/src/PVE/Network/SDN.pm
+++ b/src/PVE/Network/SDN.pm
@@ -150,15 +150,13 @@ sub commit_config {
     my $zones_cfg = PVE::Network::SDN::Zones::config();
     my $controllers_cfg = PVE::Network::SDN::Controllers::config();
     my $subnets_cfg = PVE::Network::SDN::Subnets::config();
-    my $dhcp_cfg = PVE::Network::SDN::Dhcp::config();
 
     my $vnets = { ids => $vnets_cfg->{ids} };
     my $zones = { ids => $zones_cfg->{ids} };
     my $controllers = { ids => $controllers_cfg->{ids} };
     my $subnets = { ids => $subnets_cfg->{ids} };
-    my $dhcp = { ids => $dhcp_cfg->{ids} };
 
-    $cfg = { version => $version, vnets => $vnets, zones => $zones, controllers => $controllers, subnets => $subnets, dhcps => $dhcp };
+    $cfg = { version => $version, vnets => $vnets, zones => $zones, controllers => $controllers, subnets => $subnets };
 
     cfs_write_file($running_cfg, $cfg);
 }
diff --git a/src/PVE/Network/SDN/Dhcp.pm b/src/PVE/Network/SDN/Dhcp.pm
index b92c73a..e4c4078 100644
--- a/src/PVE/Network/SDN/Dhcp.pm
+++ b/src/PVE/Network/SDN/Dhcp.pm
@@ -20,41 +20,6 @@ PVE::Network::SDN::Dhcp::Plugin->init();
 PVE::Network::SDN::Dhcp::Dnsmasq->register();
 PVE::Network::SDN::Dhcp::Dnsmasq->init();
 
-sub config {
-    my ($running) = @_;
-
-    if ($running) {
-	my $cfg = PVE::Network::SDN::running_config();
-	return $cfg->{dhcps};
-    }
-
-    return cfs_read_file('sdn/dhcp.cfg');
-}
-
-sub sdn_dhcps_config {
-    my ($cfg, $id, $noerr) = @_;
-
-    die "No DHCP ID specified!\n" if !$id;
-
-    my $dhcp_config = $cfg->{ids}->{$id};
-    die "SDN DHCP '$id' does not exist!\n" if (!$noerr && !$dhcp_config);
-
-    if ($dhcp_config) {
-	$dhcp_config->{id} = $id;
-    }
-
-    return $dhcp_config;
-}
-
-sub get_dhcp {
-    my ($dhcp_id, $running) = @_;
-
-    return if !$dhcp_id;
-
-    my $cfg = PVE::Network::SDN::Dhcp::config($running);
-    return PVE::Network::SDN::Dhcp::sdn_dhcps_config($cfg, $dhcp_id, 1);
-}
-
 sub add_mapping {
     my ($vmid, $vnet, $mac) = @_;
 
@@ -127,58 +92,52 @@ sub remove_mapping {
 sub regenerate_config {
     my ($reload) = @_;
 
-    my $dhcps = PVE::Network::SDN::Dhcp::config();
-    my $subnets = PVE::Network::SDN::Subnets::config();
+    my $cfg = PVE::Network::SDN::running_config();
 
-    my $plugins = PVE::Network::SDN::Dhcp::Plugin->lookup_types();
+    my $zone_cfg = $cfg->{zones};
+    my $subnet_cfg = $cfg->{subnets};
+    return if !$zone_cfg && !$subnet_cfg;
 
     my $nodename = PVE::INotify::nodename();
 
+    my $plugins = PVE::Network::SDN::Dhcp::Plugin->lookup_types();
+
     foreach my $plugin_name (@$plugins) {
 	my $plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($plugin_name);
-
 	eval { $plugin->before_regenerate() };
 	die "Could not run before_regenerate for DHCP plugin $plugin_name $@\n" if $@;
     }
 
-    foreach my $dhcp_id (keys %{$dhcps->{ids}}) {
-	my $dhcp_config = PVE::Network::SDN::Dhcp::sdn_dhcps_config($dhcps, $dhcp_id);
-	my $plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($dhcp_config->{type});
+    foreach my $zoneid (sort keys %{$zone_cfg->{ids}}) {
+        my $zone = $zone_cfg->{ids}->{$zoneid};
+        next if defined($zone->{nodes}) && !$zone->{nodes}->{$nodename};
 
-	eval { $plugin->before_configure($dhcp_config) };
-	die "Could not run before_configure for DHCP server $dhcp_id $@\n" if $@;
-    }
+	my $dhcp_plugin_name = $zone->{dhcp};
+	my $dhcp_plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($dhcp_plugin_name);
 
-    foreach my $subnet_id (keys %{$subnets->{ids}}) {
-	my $subnet_config = PVE::Network::SDN::Subnets::sdn_subnets_config($subnets, $subnet_id);
-	next if !$subnet_config->{'dhcp-range'};
+	eval { $dhcp_plugin->before_configure($zoneid) };
+	die "Could not run before_configure for DHCP server $zoneid $@\n" if $@;
 
-	my @configured_servers = ();
 
-	foreach my $dhcp_range (@{$subnet_config->{'dhcp-range'}}) {
-	    my $dhcp_config = PVE::Network::SDN::Dhcp::sdn_dhcps_config($dhcps, $dhcp_range->{server});
-	    my $plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($dhcp_config->{type});
+	foreach my $subnet_id (keys %{$subnet_cfg->{ids}}) {
+	    my $subnet_config = PVE::Network::SDN::Subnets::sdn_subnets_config($subnet_cfg, $subnet_id);
+	    my ($zone, $subnet_network, $subnet_mask) = split(/-/, $subnet_id);
+	    next if $zone ne $zoneid;
+	    next if !$subnet_config->{'dhcp-range'};
 
-	    next if $dhcp_config->{node} && !grep(/^$nodename$/, @{$dhcp_config->{node}});
+	    eval { $dhcp_plugin->configure_subnet($zoneid, $subnet_config) };
+	    warn "Could not configure subnet $subnet_id: $@\n" if $@;
 
-	    if (!grep(/^$subnet_id$/, @configured_servers)) {
-		eval { $plugin->configure_subnet($dhcp_config, $subnet_config) };
-		warn "Could not configure Subnet $subnet_id: $@\n" if $@;
 
-		push @configured_servers, $subnet_id;
+	    foreach my $dhcp_range (@{$subnet_config->{'dhcp-range'}}) {
+		eval { $dhcp_plugin->configure_range($zoneid, $subnet_config, $dhcp_range) };
+		warn "Could not configure DHCP range for $subnet_id: $@\n" if $@;
 	    }
-
-	    eval { $plugin->configure_range($dhcp_config, $subnet_config, $dhcp_range) };
-	    warn "Could not configure DHCP range for $subnet_id: $@\n" if $@;
 	}
-    }
 
-    foreach my $dhcp_id (keys %{$dhcps->{ids}}) {
-	my $dhcp_config = PVE::Network::SDN::Dhcp::sdn_dhcps_config($dhcps, $dhcp_id);
-	my $plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($dhcp_config->{type});
+	eval { $dhcp_plugin->after_configure($zoneid) };
+	warn "Could not run after_configure for DHCP server $zoneid $@\n" if $@;
 
-	eval { $plugin->after_configure($dhcp_config) };
-	warn "Could not run after_configure for DHCP server $dhcp_id $@\n" if $@;
     }
 
     foreach my $plugin_name (@$plugins) {
diff --git a/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm b/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
index af109b8..64895ef 100644
--- a/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
+++ b/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
@@ -19,9 +19,9 @@ sub type {
 }
 
 sub del_ip_mapping {
-    my ($class, $dhcp_config, $mac) = @_;
+    my ($class, $dhcpid, $mac) = @_;
 
-    my $ethers_file = "$DNSMASQ_CONFIG_ROOT/$dhcp_config->{id}/ethers";
+    my $ethers_file = "$DNSMASQ_CONFIG_ROOT/$dhcpid/ethers";
     my $ethers_tmp_file = "$ethers_file.tmp";
 
     my $removeFn = sub {
@@ -48,13 +48,13 @@ sub del_ip_mapping {
 	return;
     }
 
-    my $service_name = "dnsmasq\@$dhcp_config->{id}";
+    my $service_name = "dnsmasq\@$dhcpid";
     PVE::Tools::run_command(['systemctl', 'reload', $service_name]);
 }
 
 sub add_ip_mapping {
-    my ($class, $dhcp_config, $mac, $ip) = @_;
-    my $ethers_file = "$DNSMASQ_CONFIG_ROOT/$dhcp_config->{id}/ethers";
+    my ($class, $dhcpid, $mac, $ip) = @_;
+    my $ethers_file = "$DNSMASQ_CONFIG_ROOT/$dhcpid/ethers";
 
     my $appendFn = sub {
 	open(my $fh, '>>', $ethers_file) or die "Could not open file '$ethers_file' $!\n";
@@ -69,12 +69,12 @@ sub add_ip_mapping {
 	return;
     }
 
-    my $service_name = "dnsmasq\@$dhcp_config->{id}";
+    my $service_name = "dnsmasq\@$dhcpid";
     PVE::Tools::run_command(['systemctl', 'reload', $service_name]);
 }
 
 sub configure_subnet {
-    my ($class, $dhcp_config, $subnet_config) = @_;
+    my ($class, $dhcpid, $subnet_config) = @_;
 
     die "No gateway defined for subnet $subnet_config->{id}"
 	if !$subnet_config->{gateway};
@@ -98,15 +98,15 @@ sub configure_subnet {
 	if $subnet_config->{'dhcp-dns-server'};
 
     PVE::Tools::file_set_contents(
-	"$DNSMASQ_CONFIG_ROOT/$dhcp_config->{id}/10-$subnet_config->{id}.conf",
+	"$DNSMASQ_CONFIG_ROOT/$dhcpid/10-$subnet_config->{id}.conf",
 	join("\n", @dnsmasq_config) . "\n"
     );
 }
 
 sub configure_range {
-    my ($class, $dhcp_config, $subnet_config, $range_config) = @_;
+    my ($class, $dhcpid, $subnet_config, $range_config) = @_;
 
-    my $range_file = "$DNSMASQ_CONFIG_ROOT/$dhcp_config->{id}/10-$subnet_config->{id}.ranges.conf",
+    my $range_file = "$DNSMASQ_CONFIG_ROOT/$dhcpid/10-$subnet_config->{id}.ranges.conf",
     my $tag = $subnet_config->{id};
 
     open(my $fh, '>>', $range_file) or die "Could not open file '$range_file' $!\n";
@@ -115,9 +115,9 @@ sub configure_range {
 }
 
 sub before_configure {
-    my ($class, $dhcp_config) = @_;
+    my ($class, $dhcpid) = @_;
 
-    my $config_directory = "$DNSMASQ_CONFIG_ROOT/$dhcp_config->{id}";
+    my $config_directory = "$DNSMASQ_CONFIG_ROOT/$dhcpid";
 
     mkdir($config_directory, 755) if !-d $config_directory;
 
@@ -127,7 +127,7 @@ DNSMASQ_OPTS="--conf-file=/dev/null"
 CFG
 
     PVE::Tools::file_set_contents(
-	"$DNSMASQ_DEFAULT_ROOT/dnsmasq.$dhcp_config->{id}",
+	"$DNSMASQ_DEFAULT_ROOT/dnsmasq.$dhcpid",
 	$default_config
     );
 
@@ -136,7 +136,7 @@ except-interface=lo
 bind-dynamic
 no-resolv
 no-hosts
-dhcp-leasefile=$DNSMASQ_LEASE_ROOT/dnsmasq.$dhcp_config->{id}.leases
+dhcp-leasefile=$DNSMASQ_LEASE_ROOT/dnsmasq.$dhcpid.leases
 dhcp-hostsfile=$config_directory/ethers
 dhcp-ignore=tag:!known
 
@@ -163,9 +163,9 @@ CFG
 }
 
 sub after_configure {
-    my ($class, $dhcp_config) = @_;
+    my ($class, $dhcpid) = @_;
 
-    my $service_name = "dnsmasq\@$dhcp_config->{id}";
+    my $service_name = "dnsmasq\@$dhcpid";
 
     PVE::Tools::run_command(['systemctl', 'enable', $service_name]);
     PVE::Tools::run_command(['systemctl', 'restart', $service_name]);
diff --git a/src/PVE/Network/SDN/Dhcp/Plugin.pm b/src/PVE/Network/SDN/Dhcp/Plugin.pm
index 75979e8..7b9e9b7 100644
--- a/src/PVE/Network/SDN/Dhcp/Plugin.pm
+++ b/src/PVE/Network/SDN/Dhcp/Plugin.pm
@@ -8,23 +8,13 @@ use PVE::JSONSchema qw(get_standard_option);
 
 use base qw(PVE::SectionConfig);
 
-PVE::Cluster::cfs_register_file('sdn/dhcp.cfg',
-    sub { __PACKAGE__->parse_config(@_); },
-    sub { __PACKAGE__->write_config(@_); },
-);
-
 my $defaultData = {
     propertyList => {
-	type => {
-	    description => "Plugin type.",
-	    format => 'pve-configid',
-	    type => 'string',
-	},
-	node => {
-	    type => 'array',
-	    description => 'A list of nodes where this DHCP server should be deployed',
-	    items => get_standard_option('pve-node'),
-	},
+       type => {
+           description => "Plugin type.",
+           format => 'pve-configid',
+           type => 'string',
+       },
     },
 };
 
@@ -32,14 +22,6 @@ sub private {
     return $defaultData;
 }
 
-sub options {
-    return {
-	node => {
-	    optional => 1,
-	},
-    };
-}
-
 sub add_ip_mapping {
     my ($class, $dhcp_config, $mac, $ip) = @_;
     die 'implement in sub class';
diff --git a/src/PVE/Network/SDN/SubnetPlugin.pm b/src/PVE/Network/SDN/SubnetPlugin.pm
index 47b8406..8447ece 100644
--- a/src/PVE/Network/SDN/SubnetPlugin.pm
+++ b/src/PVE/Network/SDN/SubnetPlugin.pm
@@ -62,10 +62,6 @@ sub private {
 }
 
 my $dhcp_range_fmt = {
-    server => {
-	type => 'pve-configid',
-	description => 'ID of the DHCP server responsible for managing this range',
-    },
     'start-address' => {
 	type => 'ip',
 	description => 'Start address for the DHCP IP range',
diff --git a/src/PVE/Network/SDN/Zones/SimplePlugin.pm b/src/PVE/Network/SDN/Zones/SimplePlugin.pm
index 4922903..f30278c 100644
--- a/src/PVE/Network/SDN/Zones/SimplePlugin.pm
+++ b/src/PVE/Network/SDN/Zones/SimplePlugin.pm
@@ -26,7 +26,11 @@ sub properties {
 	dnszone => {
 	    type => 'string', format => 'dns-name',
 	    description => "dns domain zone  ex: mydomain.com",
-	}
+	},
+	dhcp => {
+	    type => 'pve-configid',
+	    description => 'ID of the DHCP server responsible for managing this range',
+	},
     };
 }
 
@@ -38,6 +42,7 @@ sub options {
 	reversedns => { optional => 1 },
 	dnszone => { optional => 1 },
 	ipam => { optional => 1 },
+	dhcp => { optional => 1 },
     };
 }
 
-- 
2.39.2





More information about the pve-devel mailing list