From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 4BE5B79AAD for ; Wed, 5 May 2021 12:07:10 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 4245313937 for ; Wed, 5 May 2021 12:06:40 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 514301391B for ; Wed, 5 May 2021 12:06:39 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 28F4440A76; Wed, 5 May 2021 12:06:39 +0200 (CEST) Message-ID: Date: Wed, 5 May 2021 12:06:37 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Thunderbird/89.0 Content-Language: en-US To: Proxmox VE development discussion , Alexandre Derumier References: <20210429225547.2272077-1-aderumier@odiso.com> From: Thomas Lamprecht In-Reply-To: <20210429225547.2272077-1-aderumier@odiso.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.005 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_SHORT 0.001 Use of a URL Shortener for very short URL NICE_REPLY_A -0.001 Looks like a legit reply (A) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [gnu.org, mycustomipamplugin.pm, ipams.pm] Subject: Re: [pve-devel] [PATCH pve-network] ipam: add custom plugins support X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 May 2021 10:07:10 -0000 On 30.04.21 00:55, Alexandre Derumier wrote: > Same than for storage > FYI, from a quick look this seems OK, but I'll wait at least until we have VM and CT support ready before applying this. > Signed-off-by: Alexandre Derumier > --- > 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; > + > + >