[pve-devel] [PATCH pve-network] ipam: add custom plugins support

Alexandre Derumier aderumier at odiso.com
Fri Apr 30 00:55:47 CEST 2021


Same than for storage

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/Network/SDN/Ipams.pm         | 48 ++++++++++++++++++++-
 test/debug/MyCustomIpamPlugin.pm | 72 ++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+), 2 deletions(-)
 create mode 100644 test/debug/MyCustomIpamPlugin.pm

diff --git a/PVE/Network/SDN/Ipams.pm b/PVE/Network/SDN/Ipams.pm
index e8a4b0b..3d7f328 100644
--- a/PVE/Network/SDN/Ipams.pm
+++ b/PVE/Network/SDN/Ipams.pm
@@ -5,7 +5,7 @@ use warnings;
 
 use JSON;
 
-use PVE::Tools qw(extract_param dir_glob_regex run_command);
+use PVE::Tools qw(extract_param dir_glob_regex run_command dir_glob_foreach);
 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::Network;
 
@@ -14,11 +14,55 @@ use PVE::Network::SDN::Ipams::NetboxPlugin;
 use PVE::Network::SDN::Ipams::PhpIpamPlugin;
 use PVE::Network::SDN::Ipams::Plugin;
 
+# Storage API version. Increment it on changes in storage API interface.
+use constant APIVER => 1;
+# Age is the number of versions we're backward compatible with.
+# This is like having 'current=APIVER' and age='APIAGE' in libtool,
+# see https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
+use constant APIAGE => 1;
+
 PVE::Network::SDN::Ipams::PVEPlugin->register();
 PVE::Network::SDN::Ipams::NetboxPlugin->register();
 PVE::Network::SDN::Ipams::PhpIpamPlugin->register();
-PVE::Network::SDN::Ipams::Plugin->init();
 
+# load third-party plugins
+if ( -d '/usr/share/perl5/PVE/Network/SDN/Ipams/Custom' ) {
+    dir_glob_foreach('/usr/share/perl5/PVE/Network/SDN/Ipams/Custom', '.*\.pm$', sub {
+	my ($file) = @_;
+	my $modname = 'PVE::Network::SDN::Ipams::Custom::' . $file;
+	$modname =~ s!\.pm$!!;
+	$file = 'PVE/Network/SDN/Ipams/Custom/' . $file;
+
+	eval {
+	    require $file;
+
+	    # Check perl interface:
+	    die "not derived from PVE::Network::SDN::Ipams::Plugin\n"
+		if !$modname->isa('PVE::Network::SDN::Ipams::Plugin');
+	    die "does not provide an api() method\n"
+		if !$modname->can('api');
+	    # Check storage API version and that file is really ipam plugin.
+	    my $version = $modname->api();
+	    die "implements an API version newer than current ($version > " . APIVER . ")\n"
+		if $version > APIVER;
+	    my $min_version = (APIVER - APIAGE);
+	    die "API version too old, please update the plugin ($version < $min_version)\n"
+		if $version < $min_version;
+	    import $file;
+	    $modname->register();
+
+	    # If we got this far and the API version is not the same, make some
+	    # noise:
+	    warn "Plugin \"$modname\" is implementing an older ipam API, an upgrade is recommended\n"
+		if $version != APIVER;
+	};
+	if ($@) {
+	    warn "Error loading storage plugin \"$modname\": $@";
+	}
+    });
+}
+
+PVE::Network::SDN::Ipams::Plugin->init();
 
 sub sdn_ipams_config {
     my ($cfg, $id, $noerr) = @_;
diff --git a/test/debug/MyCustomIpamPlugin.pm b/test/debug/MyCustomIpamPlugin.pm
new file mode 100644
index 0000000..e923478
--- /dev/null
+++ b/test/debug/MyCustomIpamPlugin.pm
@@ -0,0 +1,72 @@
+package PVE::Network::SDN::Ipams::Custom::MyCustomIpamPlugin;
+
+use strict;
+use warnings;
+use PVE::INotify;
+use PVE::Cluster;
+use PVE::Tools;
+
+use base('PVE::Network::SDN::Ipams::Plugin');
+
+sub type {
+    return 'mycustomipam';
+}
+
+sub api {
+    return 1;
+}
+
+sub options {
+
+    return {
+        url => { optional => 0},
+        token => { optional => 0 },
+        section => { optional => 0 },
+    };
+}
+
+# Plugin implementation
+
+sub add_subnet {
+    my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
+
+}
+
+sub del_subnet {
+    my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
+
+}
+
+sub add_ip {
+    my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
+
+}
+
+sub update_ip {
+    my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
+
+}
+
+sub add_next_freeip {
+    my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description, $noerr) = @_;
+
+}
+
+sub del_ip {
+    my ($class, $plugin_config, $subnetid, $subnet, $ip, $noerr) = @_;
+
+}
+
+sub verify_api {
+    my ($class, $plugin_config) = @_;
+
+}
+
+sub on_update_hook {
+    my ($class, $plugin_config) = @_;
+
+}
+
+1;
+
+
-- 
2.20.1





More information about the pve-devel mailing list