From: Alexandre Derumier <aderumier@odiso.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v7 pve-network 18/21] add vnet to subnets && remove subnetlist from vnet
Date: Fri, 28 Aug 2020 14:36:46 +0200 [thread overview]
Message-ID: <20200828123649.11125-19-aderumier@odiso.com> (raw)
In-Reply-To: <20200828123649.11125-1-aderumier@odiso.com>
---
PVE/API2/Network/SDN/Subnets.pm | 31 +-------------
PVE/Network/SDN/SubnetPlugin.pm | 59 ++++++++++++++++++++-------
PVE/Network/SDN/Subnets.pm | 34 +++++++++------
PVE/Network/SDN/VnetPlugin.pm | 23 ++++-------
PVE/Network/SDN/Vnets.pm | 43 ++++++++++++-------
PVE/Network/SDN/Zones/EvpnPlugin.pm | 10 ++---
PVE/Network/SDN/Zones/SimplePlugin.pm | 16 ++++----
7 files changed, 117 insertions(+), 99 deletions(-)
diff --git a/PVE/API2/Network/SDN/Subnets.pm b/PVE/API2/Network/SDN/Subnets.pm
index 094401c..728b939 100644
--- a/PVE/API2/Network/SDN/Subnets.pm
+++ b/PVE/API2/Network/SDN/Subnets.pm
@@ -135,17 +135,7 @@ __PACKAGE__->register_method ({
}
$cfg->{ids}->{$id} = $opts;
- PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $cfg);
-
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $ipam = $cfg->{ids}->{$id}->{ipam};
- if ($ipam) {
- raise_param_exc({ ipam => "$ipam not existing"}) if !$ipam_cfg->{ids}->{$ipam};
- my $plugin_config = $ipam_cfg->{ids}->{$ipam};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->add_subnet($plugin_config, $id, $cfg->{ids}->{$id});
- $plugin->add_ip($plugin_config, $id, $opts->{gateway}, 1) if $opts->{gateway};
- }
+ PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $opts);
PVE::Network::SDN::Subnets::write_config($cfg);
@@ -182,24 +172,7 @@ __PACKAGE__->register_method ({
my $opts = PVE::Network::SDN::SubnetPlugin->check_config($id, $param, 0, 1);
$cfg->{ids}->{$id} = $opts;
- PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $cfg);
-
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $ipam = $cfg->{ids}->{$id}->{ipam};
- if ($ipam) {
- raise_param_exc({ ipam => "$ipam not existing"}) if !$ipam_cfg->{ids}->{$ipam};
- my $plugin_config = $ipam_cfg->{ids}->{$ipam};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->add_subnet($plugin_config, $id, $cfg->{ids}->{$id});
-
- if($opts->{gateway} && $scfg->{gateway} && $opts->{gateway} ne $scfg->{gateway}) {
- $plugin->del_ip($plugin_config, $id, $scfg->{gateway});
- }
- if (!defined($opts->{gateway}) && $scfg->{gateway}) {
- $plugin->del_ip($plugin_config, $id, $scfg->{gateway});
- }
- $plugin->add_ip($plugin_config, $id, $opts->{gateway}, 1) if $opts->{gateway};
- }
+ PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $opts, $scfg);
PVE::Network::SDN::Subnets::write_config($cfg);
diff --git a/PVE/Network/SDN/SubnetPlugin.pm b/PVE/Network/SDN/SubnetPlugin.pm
index bc66b82..84303d1 100644
--- a/PVE/Network/SDN/SubnetPlugin.pm
+++ b/PVE/Network/SDN/SubnetPlugin.pm
@@ -8,6 +8,8 @@ use base qw(PVE::SectionConfig);
use PVE::JSONSchema qw(get_standard_option);
use PVE::Exception qw(raise raise_param_exc);
use Net::Subnet qw(subnet_matcher);
+use PVE::Network::SDN::Vnets;
+use PVE::Network::SDN::Ipams;
PVE::Cluster::cfs_register_file('sdn/subnets.cfg',
sub { __PACKAGE__->parse_config(@_); },
@@ -52,6 +54,10 @@ sub private {
sub properties {
return {
+ vnet => {
+ type => 'string',
+ description => "associated vnet",
+ },
gateway => {
type => 'string', format => 'ip',
description => "Subnet Gateway: Will be assign on vnet for layer3 zones",
@@ -94,6 +100,7 @@ sub properties {
sub options {
return {
+ vnet => { optional => 1 },
gateway => { optional => 1 },
routes => { optional => 1 },
snat => { optional => 1 },
@@ -107,44 +114,66 @@ sub options {
}
sub on_update_hook {
- my ($class, $subnetid, $subnet_cfg) = @_;
+ my ($class, $subnetid, $subnet, $old_subnet) = @_;
my $cidr = $subnetid =~ s/-/\//r;
my $subnet_matcher = subnet_matcher($cidr);
- my $subnet = $subnet_cfg->{ids}->{$subnetid};
-
+ my $vnetid = $subnet->{vnet};
my $gateway = $subnet->{gateway};
+ my $ipam = $subnet->{ipam};
my $dns = $subnet->{dns};
my $dnszone = $subnet->{dnszone};
my $reversedns = $subnet->{reversedns};
my $reversednszone = $subnet->{reversednszone};
- my ($ip, $mask) = split(/\//, $cidr);
+ my $old_gateway = $old_subnet->{gateway} if $old_subnet;
+ if($vnetid) {
+ my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
+ raise_param_exc({ vnet => "$vnetid don't exist"}) if !$vnet;
+ }
+
+ my ($ip, $mask) = split(/\//, $cidr);
#for /32 pointopoint, we allow gateway outside the subnet
- raise_param_exc({ gateway => "$gateway is not in subnet $subnet"}) if $gateway && !$subnet_matcher->($gateway) && $mask != 32;
+ raise_param_exc({ gateway => "$gateway is not in subnet $subnetid"}) if $gateway && !$subnet_matcher->($gateway) && $mask != 32;
raise_param_exc({ dns => "missing dns provider"}) if $dnszone && !$dns;
raise_param_exc({ dnszone => "missing dns zone"}) if $dns && !$dnszone;
raise_param_exc({ reversedns => "missing dns provider"}) if $reversednszone && !$reversedns;
raise_param_exc({ reversednszone => "missing dns zone"}) if $reversedns && !$reversednszone;
+ if ($ipam) {
+ my $ipam_cfg = PVE::Network::SDN::Ipams::config();
+ my $plugin_config = $ipam_cfg->{ids}->{$ipam};
+ raise_param_exc({ ipam => "$ipam not existing"}) if !$plugin_config;
+ my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
+ $plugin->add_subnet($plugin_config, $subnetid, $subnet);
+
+ #delete on removal
+ if (!defined($gateway) && $old_gateway) {
+ eval {
+ PVE::Network::SDN::Subnets::del_ip($subnetid, $old_subnet, $old_gateway);
+ };
+ warn if $@;
+ }
+ if(!$old_gateway || $gateway && $gateway ne $old_gateway) {
+ PVE::Network::SDN::Subnets::add_ip($subnetid, $subnet, $gateway);
+ }
+
+ #delete old ip after update
+ if($gateway && $old_gateway && $gateway ne $old_gateway) {
+ eval {
+ PVE::Network::SDN::Subnets::del_ip($subnetid, $old_subnet, $old_gateway);
+ };
+ warn if $@;
+ }
+ }
}
sub on_delete_hook {
my ($class, $subnetid, $subnet_cfg, $vnet_cfg) = @_;
- #verify if vnets have subnet
- foreach my $vnetid (keys %{$vnet_cfg->{ids}}) {
- my $vnet = $vnet_cfg->{ids}->{$vnetid};
- my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
- foreach my $subnet (@subnets) {
- my $id = $subnet =~ s/\//-/r;
- raise_param_exc({ subnet => "$subnet is attached to vnet $vnetid"}) if $id eq $subnetid;
- }
- }
-
return;
}
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index 4e8353e..d20af9e 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -57,20 +57,18 @@ sub get_subnet {
}
sub find_ip_subnet {
- my ($ip, $subnetslist) = @_;
-
- my $subnets_cfg = PVE::Network::SDN::Subnets::config();
- my @subnets = PVE::Tools::split_list($subnetslist) if $subnetslist;
+ my ($ip, $subnets) = @_;
my $subnet = undef;
my $subnetid = undef;
- foreach my $s (@subnets) {
- my $subnet_matcher = subnet_matcher($s);
- next if !$subnet_matcher->($ip);
- $subnetid = $s =~ s/\//-/r;
- $subnet = $subnets_cfg->{ids}->{$subnetid};
- last;
+ foreach my $id (sort keys %{$subnets}) {
+ my $cidr = $id =~ s/-/\//r;
+ my $subnet_matcher = subnet_matcher($cidr);
+ next if !$subnet_matcher->($ip);
+ $subnet = $subnets->{$id};
+ $subnetid = $id;
+ last;
}
die "can't find any subnet for ip $ip" if !$subnet;
@@ -143,8 +141,11 @@ sub next_free_ip {
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet);
- ($ip, undef) = split(/\//, $cidr);
+ eval {
+ $cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet);
+ ($ip, undef) = split(/\//, $cidr);
+ };
+ die $@ if $@;
}
eval {
@@ -167,6 +168,8 @@ sub next_free_ip {
sub add_ip {
my ($subnetid, $subnet, $ip, $hostname) = @_;
+ return if !$subnet;
+
my $ipamid = $subnet->{ipam};
my $dns = $subnet->{dns};
my $dnszone = $subnet->{dnszone};
@@ -182,7 +185,10 @@ sub add_ip {
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->add_ip($plugin_config, $subnetid, $ip);
+ eval {
+ $plugin->add_ip($plugin_config, $subnetid, $ip);
+ };
+ die $@ if $@;
}
eval {
@@ -204,6 +210,8 @@ sub add_ip {
sub del_ip {
my ($subnetid, $subnet, $ip, $hostname) = @_;
+ return if !$subnet;
+
my $ipamid = $subnet->{ipam};
my $dns = $subnet->{dns};
my $dnszone = $subnet->{dnszone};
diff --git a/PVE/Network/SDN/VnetPlugin.pm b/PVE/Network/SDN/VnetPlugin.pm
index 6b2bcc8..47fd4d4 100644
--- a/PVE/Network/SDN/VnetPlugin.pm
+++ b/PVE/Network/SDN/VnetPlugin.pm
@@ -68,11 +68,6 @@ sub properties {
description => "alias name of the vnet",
optional => 1,
},
- subnets => {
- type => 'string',
- description => "Subnets list",
- optional => 1,
- },
mac => {
type => 'string',
description => "Anycast router mac address",
@@ -86,16 +81,21 @@ sub options {
zone => { optional => 0},
tag => { optional => 1},
alias => { optional => 1 },
- subnets => { optional => 1 },
mac => { optional => 1 },
vlanaware => { optional => 1 },
};
}
sub on_delete_hook {
- my ($class, $sdnid, $vnet_cfg) = @_;
+ my ($class, $vnetid, $vnet_cfg) = @_;
- return;
+ #verify if subnets are associated
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
+ my @subnetlist = ();
+ foreach my $subnetid (sort keys %{$subnets}) {
+ push @subnetlist, $subnetid;
+ }
+ raise_param_exc({ vnet => "Vnet is attached to following subnets:". join(',', @subnetlist)}) if @subnetlist > 0;
}
sub on_update_hook {
@@ -111,13 +111,6 @@ sub on_update_hook {
}
}
}
-
- #verify subnet
- my @subnets = PVE::Tools::split_list($vnet_cfg->{ids}->{$vnetid}->{subnets}) if $vnet_cfg->{ids}->{$vnetid}->{subnets};
- foreach my $subnet (@subnets) {
- my $id = $subnet =~ s/\//-/r;
- raise_param_exc({ subnet => "$subnet not existing"}) if !$subnet_cfg->{ids}->{$id};
- }
}
1;
diff --git a/PVE/Network/SDN/Vnets.pm b/PVE/Network/SDN/Vnets.pm
index c9916b1..7cec418 100644
--- a/PVE/Network/SDN/Vnets.pm
+++ b/PVE/Network/SDN/Vnets.pm
@@ -54,22 +54,35 @@ sub get_vnet {
return $vnet;
}
+sub get_subnets {
+ my ($vnetid) = @_;
+
+ my $subnets = {};
+ my $subnets_cfg = PVE::Network::SDN::Subnets::config();
+ foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) {
+ my $subnet = $subnets_cfg->{ids}->{$subnetid};
+ next if !$subnet->{vnet} || $subnet->{vnet} ne $vnetid;
+ $subnets->{$subnetid} = $subnet;
+ }
+ return $subnets;
+
+}
+
sub get_next_free_ip {
- my ($vnet, $hostname, $ipversion) = @_;
+ my ($vnetid, $hostname, $ipversion) = @_;
$ipversion = 4 if !$ipversion;
- my $subnets_cfg = PVE::Network::SDN::Subnets::config();
- my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
my $ip = undef;
- my $subnet = undef;
my $subnetcount = 0;
- foreach my $s (@subnets) {
- my $subnetid = $s =~ s/\//-/r;
+
+ foreach my $subnetid (sort keys %{$subnets}) {
+ my $subnet = $subnets->{$subnetid};
my ($network, $mask) = split(/-/, $subnetid);
+
next if $ipversion != Net::IP::ip_get_version($network);
$subnetcount++;
- $subnet = $subnets_cfg->{ids}->{$subnetid};
- if ($subnet && $subnet->{ipam}) {
+ if ($subnet->{ipam}) {
eval {
$ip = PVE::Network::SDN::Subnets::next_free_ip($subnetid, $subnet, $hostname);
};
@@ -83,21 +96,23 @@ sub get_next_free_ip {
}
sub add_ip {
- my ($vnet, $cidr, $hostname) = @_;
+ my ($vnetid, $cidr, $hostname) = @_;
+
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
my ($ip, $mask) = split(/\//, $cidr);
- my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $vnet->{subnets});
- return if !$subnet->{ipam};
+ my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets);
PVE::Network::SDN::Subnets::add_ip($subnetid, $subnet, $ip, $hostname);
}
sub del_ip {
- my ($vnet, $cidr, $hostname) = @_;
+ my ($vnetid, $cidr, $hostname) = @_;
+
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
my ($ip, $mask) = split(/\//, $cidr);
- my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $vnet->{subnets});
- return if !$subnet->{ipam};
+ my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets);
PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostname);
}
diff --git a/PVE/Network/SDN/Zones/EvpnPlugin.pm b/PVE/Network/SDN/Zones/EvpnPlugin.pm
index 17c9262..ff25f12 100644
--- a/PVE/Network/SDN/Zones/EvpnPlugin.pm
+++ b/PVE/Network/SDN/Zones/EvpnPlugin.pm
@@ -76,12 +76,12 @@ sub generate_sdn_config {
#vnet bridge
@iface_config = ();
- my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
my $address = {};
- foreach my $subnet (@subnets) {
- my $subnetid = $subnet =~ s/\//-/r;
- next if !defined($subnet_cfg->{ids}->{$subnetid});
- my $gateway = $subnet_cfg->{ids}->{$subnetid}->{gateway};
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
+ foreach my $subnetid (sort keys %{$subnets}) {
+ my $subnet = $subnets->{$subnetid};
+ my $cidr = $subnetid =~ s/-/\//r;
+ my $gateway = $subnet->{gateway};
if ($gateway) {
push @iface_config, "address $gateway" if !defined($address->{$gateway});
$address->{$gateway} = 1;
diff --git a/PVE/Network/SDN/Zones/SimplePlugin.pm b/PVE/Network/SDN/Zones/SimplePlugin.pm
index a1733d5..a4299dd 100644
--- a/PVE/Network/SDN/Zones/SimplePlugin.pm
+++ b/PVE/Network/SDN/Zones/SimplePlugin.pm
@@ -35,19 +35,19 @@ sub generate_sdn_config {
# vnet bridge
my @iface_config = ();
- my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
my $address = {};
- foreach my $subnet (@subnets) {
- my $subnetid = $subnet =~ s/\//-/r;
- next if !defined($subnet_cfg->{ids}->{$subnetid});
- my $gateway = $subnet_cfg->{ids}->{$subnetid}->{gateway};
- if ($gateway) {
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
+ foreach my $subnetid (sort keys %{$subnets}) {
+ my $subnet = $subnets->{$subnetid};
+ my $cidr = $subnetid =~ s/-/\//r;
+ my $gateway = $subnet->{gateway};
+ if ($gateway) {
push @iface_config, "address $gateway" if !defined($address->{$gateway});
$address->{$gateway} = 1;
}
#add route for /32 pointtopoint
- my ($ip, $mask) = split(/\//, $subnet);
- push @iface_config, "up ip route add $subnet dev $vnetid" if $mask == 32;
+ my ($ip, $mask) = split(/\//, $cidr);
+ push @iface_config, "up ip route add $cidr dev $vnetid" if $mask == 32;
}
push @iface_config, "hwaddress $mac" if $mac;
--
2.20.1
next prev parent reply other threads:[~2020-08-28 12:37 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-28 12:36 [pve-devel] [PATCH v7 pve-network 00/21] sdn : add subnets management Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 01/21] add subnet plugin Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 02/21] vnets: add subnets Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 03/21] add subnets verifications hooks Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 04/21] zones: simple|evpn: add gateway ip from subnets to vnet Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 05/21] zone: add vnet_update_hook Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 06/21] vnets: subnets: use cidr Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 07/21] subnet: fix on_delete_hook Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 08/21] api2: subnet create: convert cidr to subnetid Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 09/21] api2: increase version on apply/reload only Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 10/21] add ipams plugins Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 11/21] add pve internal ipam plugin Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 12/21] vnets: find_free_ip : add ipversion detection Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 13/21] vnets: add add_ip Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 14/21] vnets: add del_ip + rework add_ip/find_free_ip Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 15/21] add dns plugin Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 16/21] Fix vnet gateway for routed setup + /32 pointopoint subnet Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 17/21] ipam : pveplugin : fix find_next_free_ip Alexandre Derumier
2020-08-28 12:36 ` Alexandre Derumier [this message]
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 19/21] zones: evpn|simple: add snat iptables rules Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 20/21] subnet: disable route option for now and add dns domain format Alexandre Derumier
2020-08-28 12:36 ` [pve-devel] [PATCH v7 pve-network 21/21] dns: fix reverse dns Alexandre Derumier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200828123649.11125-19-aderumier@odiso.com \
--to=aderumier@odiso.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox