public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Alexandre Derumier <aderumier@odiso.com>
To: pve-devel@pve.proxmox.com
Subject: [pve-devel] [PATCH v5 pve-network 11/14] add pve internal ipam plugin
Date: Fri, 31 Jul 2020 19:16:40 +0200	[thread overview]
Message-ID: <20200731171643.13180-12-aderumier@odiso.com> (raw)
In-Reply-To: <20200731171643.13180-1-aderumier@odiso.com>

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/API2/Network/SDN/Ipams.pm          |   1 +
 PVE/API2/Network/SDN/Subnets.pm        |   4 +-
 PVE/Network/SDN/Ipams.pm               |   2 +
 PVE/Network/SDN/Ipams/Makefile         |   2 +-
 PVE/Network/SDN/Ipams/NetboxPlugin.pm  |   4 +-
 PVE/Network/SDN/Ipams/PVEPlugin.pm     | 166 +++++++++++++++++++++++++
 PVE/Network/SDN/Ipams/PhpIpamPlugin.pm |   2 +-
 PVE/Network/SDN/Ipams/Plugin.pm        |   2 +-
 debian/control                         |   1 +
 9 files changed, 177 insertions(+), 7 deletions(-)
 create mode 100644 PVE/Network/SDN/Ipams/PVEPlugin.pm

diff --git a/PVE/API2/Network/SDN/Ipams.pm b/PVE/API2/Network/SDN/Ipams.pm
index f8665a1..0d567c8 100644
--- a/PVE/API2/Network/SDN/Ipams.pm
+++ b/PVE/API2/Network/SDN/Ipams.pm
@@ -9,6 +9,7 @@ use PVE::Cluster qw(cfs_read_file cfs_write_file);
 use PVE::Network::SDN;
 use PVE::Network::SDN::Ipams;
 use PVE::Network::SDN::Ipams::Plugin;
+use PVE::Network::SDN::Ipams::PVEPlugin;
 use PVE::Network::SDN::Ipams::PhpIpamPlugin;
 use PVE::Network::SDN::Ipams::NetboxPlugin;
 
diff --git a/PVE/API2/Network/SDN/Subnets.pm b/PVE/API2/Network/SDN/Subnets.pm
index b60db3d..094401c 100644
--- a/PVE/API2/Network/SDN/Subnets.pm
+++ b/PVE/API2/Network/SDN/Subnets.pm
@@ -193,10 +193,10 @@ __PACKAGE__->register_method ({
 		$plugin->add_subnet($plugin_config, $id, $cfg->{ids}->{$id});
 
 		if($opts->{gateway} && $scfg->{gateway} && $opts->{gateway} ne $scfg->{gateway}) {
-		    $plugin->del_ip($plugin_config, $scfg->{gateway});
+		    $plugin->del_ip($plugin_config, $id, $scfg->{gateway});
 		}
 		if (!defined($opts->{gateway}) && $scfg->{gateway}) {
-		    $plugin->del_ip($plugin_config, $scfg->{gateway});
+		    $plugin->del_ip($plugin_config, $id, $scfg->{gateway});
 		} 
 		$plugin->add_ip($plugin_config, $id, $opts->{gateway}, 1) if $opts->{gateway};
 	    }
diff --git a/PVE/Network/SDN/Ipams.pm b/PVE/Network/SDN/Ipams.pm
index 3d33632..b634020 100644
--- a/PVE/Network/SDN/Ipams.pm
+++ b/PVE/Network/SDN/Ipams.pm
@@ -10,10 +10,12 @@ use PVE::Tools qw(extract_param dir_glob_regex run_command);
 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::Network;
 
+use PVE::Network::SDN::Ipams::PVEPlugin;
 use PVE::Network::SDN::Ipams::NetboxPlugin;
 use PVE::Network::SDN::Ipams::PhpIpamPlugin;
 use PVE::Network::SDN::Ipams::Plugin;
 
+PVE::Network::SDN::Ipams::PVEPlugin->register();
 PVE::Network::SDN::Ipams::NetboxPlugin->register();
 PVE::Network::SDN::Ipams::PhpIpamPlugin->register();
 PVE::Network::SDN::Ipams::Plugin->init();
diff --git a/PVE/Network/SDN/Ipams/Makefile b/PVE/Network/SDN/Ipams/Makefile
index 884c47a..4e7d65f 100644
--- a/PVE/Network/SDN/Ipams/Makefile
+++ b/PVE/Network/SDN/Ipams/Makefile
@@ -1,4 +1,4 @@
-SOURCES=Plugin.pm PhpIpamPlugin.pm NetboxPlugin.pm
+SOURCES=Plugin.pm PhpIpamPlugin.pm NetboxPlugin.pm PVEPlugin.pm
 
 
 PERL5DIR=${DESTDIR}/usr/share/perl5
diff --git a/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
index ccc1184..c25f451 100644
--- a/PVE/Network/SDN/Ipams/NetboxPlugin.pm
+++ b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
@@ -68,7 +68,7 @@ sub del_subnet {
     return if !$internalid;
     #fixme: check that prefix is empty exluding gateway, before delete
 
-    PVE::Network::SDN::Ipams::NetboxPlugin::del_ip($class, $plugin_config, $gateway) if $gateway;
+    PVE::Network::SDN::Ipams::NetboxPlugin::del_ip($class, $plugin_config, $subnetid, $gateway) if $gateway;
 
     eval {
 	PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers);
@@ -125,7 +125,7 @@ sub add_next_freeip {
 }
 
 sub del_ip {
-    my ($class, $plugin_config, $ip) = @_;
+    my ($class, $plugin_config, $subnetid, $ip) = @_;
 
     return if !$ip;
 
diff --git a/PVE/Network/SDN/Ipams/PVEPlugin.pm b/PVE/Network/SDN/Ipams/PVEPlugin.pm
new file mode 100644
index 0000000..0dfc8a4
--- /dev/null
+++ b/PVE/Network/SDN/Ipams/PVEPlugin.pm
@@ -0,0 +1,166 @@
+package PVE::Network::SDN::Ipams::PVEPlugin;
+
+use strict;
+use warnings;
+use PVE::INotify;
+use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_register_file cfs_lock_file);
+use PVE::Tools;
+use JSON;
+use Net::IP;
+use Digest::SHA;
+
+use base('PVE::Network::SDN::Ipams::Plugin');
+
+
+my $ipamdb_file = "priv/ipam.db";
+
+PVE::Cluster::cfs_register_file($ipamdb_file,
+                                 sub { PVE::Network::SDN::Ipams::PVEPlugin->parse_config(@_); },
+                                 sub { PVE::Network::SDN::Ipams::PVEPlugin->write_config(@_); });
+
+sub type {
+    return 'pve';
+}
+
+sub properties {
+}
+
+sub options {
+}
+
+# Plugin implementation
+
+sub add_subnet {
+    my ($class, $plugin_config, $subnetid, $subnet) = @_;
+
+    my $cidr = $subnetid =~ s/-/\//r;
+    my $gateway = $subnet->{gateway};
+
+    cfs_lock_file($ipamdb_file, undef, sub {
+	my $config = read_db();
+	#create subnet
+	if (!defined($config->{subnets}->{$cidr})) {
+	    $config->{subnets}->{$cidr}->{ips} = {};
+	    write_db($config);
+	}
+    });
+    die "$@" if $@;
+}
+
+sub del_subnet {
+    my ($class, $plugin_config, $subnetid, $subnet) = @_;
+
+    my $cidr = $subnetid =~ s/-/\//r;
+
+    cfs_lock_file($ipamdb_file, undef, sub {
+
+	my $db = read_db();
+	my $ips = $db->{subnets}->{$cidr}->{ips};
+	die "can't delete subnet, not empty" if keys %{$ips} > 0;
+	delete $db->{subnets}->{$cidr};
+	write_db($db);
+    });
+    die "$@" if $@;
+
+}
+
+sub add_ip {
+    my ($class, $plugin_config, $subnetid, $ip, $is_gateway) = @_;
+
+    my $cidr = $subnetid =~ s/-/\//r;
+
+    cfs_lock_file($ipamdb_file, undef, sub {
+
+	my $db = read_db();
+	my $s = $db->{subnets}->{$cidr};
+
+	die "ip already exist" if defined($s->{ips}->{$ip});
+
+	#verify that ip is valid for this subnet
+	$s->{ips}->{$ip} = 1;
+	write_db($db);
+    });
+    die "$@" if $@;
+}
+
+sub add_next_freeip {
+    my ($class, $plugin_config, $subnetid, $subnet) = @_;
+
+    my $cidr = $subnetid =~ s/-/\//r;
+    my $freeip = undef;
+
+    cfs_lock_file($ipamdb_file, undef, sub {
+
+	my $db = read_db();
+	my $s = $db->{subnets}->{$cidr};
+
+	my $iplist = new Net::IP($cidr);
+
+	while(1) {
+	    my $ip = $iplist->ip();
+	    ++$iplist;
+	    print "nextip: $ip\n";
+	    next if defined($s->{ips}->{$ip});
+	    $freeip = $ip;
+	    last;
+	}
+
+	die "can't find free ip in subnet $cidr" if !$freeip;
+  
+	$s->{ips}->{$freeip} = 1;
+	write_db($db);
+    });
+    die "$@" if $@;
+
+    my ($network, $mask) = split(/-/, $subnetid);
+    return "$freeip/$mask";
+}
+
+sub del_ip {
+    my ($class, $plugin_config, $subnetid, $ip) = @_;
+
+    my $cidr = $subnetid =~ s/-/\//r;
+
+    cfs_lock_file($ipamdb_file, undef, sub {
+
+	my $db = read_db();
+	my $s = $db->{subnets}->{$cidr};
+	return if !$ip;
+
+	die "ip does not exist in pam" if !defined($s->{ips}->{$ip});
+	delete $s->{ips}->{$ip};
+	write_db($db);
+    });
+    die "$@" if $@;
+}
+
+#helpers
+
+sub read_db {
+    my $db = cfs_read_file($ipamdb_file);
+    return $db;
+}
+
+sub write_db {
+    my ($cfg) = @_;
+
+    my $json = to_json($cfg);
+    cfs_write_file($ipamdb_file, $json);
+}
+
+sub write_config {
+    my ($class, $filename, $cfg) = @_;
+
+    return $cfg;
+}
+
+sub parse_config {
+    my ($class, $filename, $raw) = @_;
+
+    $raw = '{}' if !defined($raw) ||$raw eq '';
+    my $cfg = from_json($raw);
+
+    return $cfg;
+}
+
+1;
diff --git a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
index 7380bf3..d7ba3ed 100644
--- a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
@@ -145,7 +145,7 @@ sub add_next_freeip {
 }
 
 sub del_ip {
-    my ($class, $plugin_config, $ip) = @_;
+    my ($class, $plugin_config, $subnetid, $ip) = @_;
 
     return if !$ip;
 
diff --git a/PVE/Network/SDN/Ipams/Plugin.pm b/PVE/Network/SDN/Ipams/Plugin.pm
index 8a44090..fc736b8 100644
--- a/PVE/Network/SDN/Ipams/Plugin.pm
+++ b/PVE/Network/SDN/Ipams/Plugin.pm
@@ -84,7 +84,7 @@ sub add_next_freeip {
 }
 
 sub del_ip {
-    my ($class, $plugin_config, $ip) = @_;
+    my ($class, $plugin_config, $subnetid, $ip) = @_;
 }
 
 
diff --git a/debian/control b/debian/control
index 8b67d74..c54f8bc 100644
--- a/debian/control
+++ b/debian/control
@@ -17,6 +17,7 @@ Depends: libpve-common-perl (>= 5.0-45),
          perl (>= 5.6.0-16),
          pve-cluster (>= 5.0-32),
          libnet-subnet-perl,
+         libnet-ip-perl,
          ${misc:Depends},
          ${perl:Depends},
 Recommends: frr-pythontools, ifupdown2
-- 
2.20.1




  parent reply	other threads:[~2020-07-31 17:17 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-31 17:16 [pve-devel] [PATCH v5 pve-network 00/14] sdn : add subnets management Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 01/14] add subnet plugin Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 02/14] vnets: add subnets Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 03/14] add subnets verifications hooks Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 04/14] zones: simple|evpn: add gateway ip from subnets to vnet Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 05/14] zone: add vnet_update_hook Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 06/14] vnets: subnets: use cidr Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 07/14] subnet: fix on_delete_hook Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 08/14] api2: subnet create: convert cidr to subnetid Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 09/14] api2: increase version on apply/reload only Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 10/14] add ipams plugins Alexandre Derumier
2020-07-31 17:16 ` Alexandre Derumier [this message]
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 12/14] vnets: find_free_ip : add ipversion detection Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 13/14] vnets: add add_ip Alexandre Derumier
2020-07-31 17:16 ` [pve-devel] [PATCH v5 pve-network 14/14] vnets: add del_ip + rework add_ip/find_free_ip 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=20200731171643.13180-12-aderumier@odiso.com \
    --to=aderumier@odiso.com \
    --cc=pve-devel@pve.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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal