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

Thomas Lamprecht t.lamprecht at proxmox.com
Wed May 5 12:06:37 CEST 2021


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 <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;
> +
> +
> 






More information about the pve-devel mailing list