public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH pve-network v3 1/3] ipam: nautobot: base plugin
       [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
@ 2025-03-06 11:08 ` lou.lecrivain--- via pve-devel
  2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 2/3] ipam: nautobot: add testing for nautobot plugin lou.lecrivain--- via pve-devel
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: lou.lecrivain--- via pve-devel @ 2025-03-06 11:08 UTC (permalink / raw)
  To: pve-devel; +Cc: lou.lecrivain, jonatan.crystall

[-- Attachment #1: Type: message/rfc822, Size: 16598 bytes --]

From: lou.lecrivain@orange.fr
To: pve-devel@lists.proxmox.com
Cc: h.duerr@proxmox.com, jonatan.crystall@gwdg.de, Lou Lecrivain <lou.lecrivain@wdz.de>
Subject: [PATCH pve-network v3 1/3] ipam: nautobot: base plugin
Date: Thu,  6 Mar 2025 12:08:29 +0100
Message-ID: <20250306110831.6426-2-lou.lecrivain@orange.fr>

From: Lou Lecrivain <lou.lecrivain@wdz.de>

This is the initial Nautobot plugin, based on the Netbox
plugin implementation.

Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 src/PVE/API2/Network/SDN/Ipams.pm           |   1 +
 src/PVE/Network/SDN/Ipams.pm                |   3 +
 src/PVE/Network/SDN/Ipams/Makefile          |   2 +-
 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm | 413 ++++++++++++++++++++
 4 files changed, 418 insertions(+), 1 deletion(-)
 create mode 100644 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm

diff --git a/src/PVE/API2/Network/SDN/Ipams.pm b/src/PVE/API2/Network/SDN/Ipams.pm
index 27ead02..8074512 100644
--- a/src/PVE/API2/Network/SDN/Ipams.pm
+++ b/src/PVE/API2/Network/SDN/Ipams.pm
@@ -12,6 +12,7 @@ use PVE::Network::SDN::Ipams::Plugin;
 use PVE::Network::SDN::Ipams::PVEPlugin;
 use PVE::Network::SDN::Ipams::PhpIpamPlugin;
 use PVE::Network::SDN::Ipams::NetboxPlugin;
+use PVE::Network::SDN::Ipams::NautobotPlugin;
 use PVE::Network::SDN::Dhcp;
 use PVE::Network::SDN::Vnets;
 use PVE::Network::SDN::Zones;
diff --git a/src/PVE/Network/SDN/Ipams.pm b/src/PVE/Network/SDN/Ipams.pm
index c689b8f..2ecb75e 100644
--- a/src/PVE/Network/SDN/Ipams.pm
+++ b/src/PVE/Network/SDN/Ipams.pm
@@ -12,11 +12,14 @@ use PVE::Network;
 
 use PVE::Network::SDN::Ipams::PVEPlugin;
 use PVE::Network::SDN::Ipams::NetboxPlugin;
+use PVE::Network::SDN::Ipams::NautobotPlugin;
 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::NautobotPlugin->register();
 PVE::Network::SDN::Ipams::PhpIpamPlugin->register();
 PVE::Network::SDN::Ipams::Plugin->init();
 
diff --git a/src/PVE/Network/SDN/Ipams/Makefile b/src/PVE/Network/SDN/Ipams/Makefile
index 4e7d65f..75e5b9a 100644
--- a/src/PVE/Network/SDN/Ipams/Makefile
+++ b/src/PVE/Network/SDN/Ipams/Makefile
@@ -1,4 +1,4 @@
-SOURCES=Plugin.pm PhpIpamPlugin.pm NetboxPlugin.pm PVEPlugin.pm
+SOURCES=Plugin.pm PhpIpamPlugin.pm NetboxPlugin.pm PVEPlugin.pm NautobotPlugin.pm
 
 
 PERL5DIR=${DESTDIR}/usr/share/perl5
diff --git a/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm b/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
new file mode 100644
index 0000000..58f7c68
--- /dev/null
+++ b/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
@@ -0,0 +1,413 @@
+package PVE::Network::SDN::Ipams::NautobotPlugin;
+
+use strict;
+use warnings;
+use PVE::INotify;
+use PVE::Cluster;
+use PVE::Tools;
+use NetAddr::IP;
+
+use base('PVE::Network::SDN::Ipams::Plugin');
+
+sub type {
+    return 'nautobot';
+}
+
+sub properties {
+    return {
+	namespace => {
+	    type => 'string',
+	},
+    };
+}
+
+sub options {
+    return {
+	url => { optional => 0 },
+	token => { optional => 0 },
+	namespace => { optional => 0 },
+    };
+}
+
+sub default_ip_status {
+    return 'Active';
+}
+
+sub default_headers {
+    my ($plugin_config) = @_;
+    my $token = $plugin_config->{token};
+
+    return [
+	'Content-Type' => "application/json", 'Authorization' => "token $token",
+	'Accept' => "application/json"
+	];
+}
+
+# implem
+
+sub add_subnet {
+    my ($class, $plugin_config, undef, $subnet, $noerr) = @_;
+
+    my $cidr = $subnet->{cidr};
+    my $gateway = $subnet->{gateway};
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+    my $internalid = get_prefix_id($url, $cidr, $headers, $noerr);
+
+    #create subnet
+    if (!$internalid) {
+	my $params = {
+	    prefix => $cidr, namespace => $namespace,
+	    status => default_ip_status()
+	};
+
+	eval {
+	    my $result = PVE::Network::SDN::api_request(
+		"POST", "$url/ipam/prefixes/", $headers, $params);
+	};
+	if ($@) {
+	    die "error adding subnet to ipam: $@" if !$noerr;
+	}
+    }
+}
+
+sub del_subnet {
+    my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
+
+    my $cidr = $subnet->{cidr};
+    my $url = $plugin_config->{url};
+    my $headers = default_headers($plugin_config);
+
+    my $internalid = get_prefix_id($url, $cidr, $headers, $noerr);
+    return if !$internalid;
+
+    # TODO check that prefix is empty before deletion
+    return;
+
+    eval {
+	PVE::Network::SDN::api_request(
+	    "DELETE", "$url/ipam/prefixes/$internalid/", $headers);
+    };
+    if ($@) {
+	die "error deleting subnet in Nautobot: $@" if !$noerr;
+    }
+}
+
+sub add_ip {
+    my ($class, $plugin_config, undef, $subnet, $ip, $hostname, $mac, undef,
+	$is_gateway, $noerr) = @_;
+
+    my $mask = $subnet->{mask};
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+    my $description = undef;
+    if ($is_gateway) {
+	$description = 'gateway'
+    } elsif ($mac) {
+	$description = "mac:$mac";
+    }
+
+    my $params = {
+	address => "$ip/$mask", type => "dhcp", dns_name => $hostname,
+	description => $description, namespace => $namespace,
+	status => default_ip_status()};
+
+    eval {
+	PVE::Network::SDN::api_request(
+	    "POST", "$url/ipam/ip-addresses/", $headers, $params);
+    };
+
+    if ($@) {
+	if($is_gateway) {
+	    die "error adding subnet ip to ipam: ip $ip already exists: $@"
+		if !$noerr && !is_ip_gateway($url, $ip, $headers, $noerr);
+	} else {
+	    die "error adding subnet ip to ipam: ip $ip already exists: $@"
+		if !$noerr;
+	}
+    }
+}
+
+sub add_next_freeip {
+    my ($class, $plugin_config, undef, $subnet, $hostname, $mac, undef,
+	$noerr) = @_;
+
+    my $cidr = $subnet->{cidr};
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+    my $internalid = get_prefix_id($url, $cidr, $headers, $noerr);
+    die "cannot find prefix $cidr in Nautobot" if !$internalid;
+
+    my $description = undef;
+    $description = "mac:$mac" if $mac;
+
+    my $params = {
+	type => "dhcp", dns_name => $hostname, description => $description,
+	namespace => $namespace, status => default_ip_status()
+    };
+
+    my $ip = eval {
+	my $result = PVE::Network::SDN::api_request(
+	    "POST",
+	    "$url/ipam/prefixes/$internalid/available-ips/",
+	    $headers,
+	    $params);
+	my ($host_ip, undef) = split(/\//, $result->{address});
+	return $host_ip;
+    };
+
+    if ($@) {
+	die "can't find free ip in subnet $cidr: $@" if !$noerr;
+    }
+    return $ip;
+}
+
+sub add_range_next_freeip {
+    my ($class, $plugin_config, $subnet, $range, $data, $noerr) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+    my $cidr = $subnet->{cidr};
+
+    # ranges are not supported natively in nautobot, hence why we have
+    # to get a little hacky.
+    my $minimal_size = NetAddr::IP->new($range->{'start-address'})
+	- NetAddr::IP->new($cidr);
+    my $internalid = get_prefix_id($url, $cidr, $headers, $noerr);
+
+    my $ip = eval {
+	my $result = PVE::Network::SDN::api_request(
+	    "GET",
+	    "$url/ipam/prefixes/$internalid/available-ips/?limit=$minimal_size",
+	    $headers);
+	# v important for NetAddr::IP comparison!
+	my @ips = map((split(/\//,$_->{address}))[0], @{$result});
+	# get 1st result
+	my $found_ip = (get_ips_within_range(
+		      $range->{'start-address'},
+		      $range->{'end-address'},
+		      @ips))[0];
+
+	die "prefix out of space in range" if !$noerr && !$found_ip;
+
+	$class->add_ip(
+	    $plugin_config, undef, $subnet, $found_ip, $data->{hostname},
+	    $data->{mac}, undef, 0, 0);
+	return $found_ip;
+    };
+
+    if ($@) {
+	die "can't find free ip in range"
+	    ." $range->{'start-address'}-$range->{'end-address'}: $@"
+	    if !$noerr;
+    }
+    return $ip;
+}
+
+
+sub update_ip {
+    my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac,
+	undef, $is_gateway, $noerr) = @_;
+
+    my $mask = $subnet->{mask};
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+    my $description = undef;
+    if ($is_gateway) {
+	$description = 'gateway'
+    } elsif ($mac) {
+	$description = "mac:$mac";
+    }
+
+    my $params = {
+	address => "$ip/$mask", type => "dhcp", dns_name => $hostname,
+	description => $description, namespace => $namespace,
+	status => default_ip_status()
+    };
+
+    my $ip_id = get_ip_id($url, $ip, $headers, $noerr);
+    die "can't find ip $ip in ipam" if !$noerr && !$ip_id;
+
+    eval {
+	PVE::Network::SDN::api_request(
+	    "PATCH", "$url/ipam/ip-addresses/$ip_id/", $headers, $params);
+    };
+    if ($@) {
+	die "error updating ip $ip: $@" if !$noerr;
+    }
+}
+
+
+sub del_ip {
+    my ($class, $plugin_config, undef, undef, $ip, $noerr) = @_;
+
+    return if !$ip;
+
+    my $url = $plugin_config->{url};
+    my $headers = default_headers($plugin_config);
+
+    my $ip_id = get_ip_id($url, $ip, $headers, $noerr);
+    die "can't find ip $ip in ipam" if !$ip_id && !$noerr;
+
+    eval {
+	PVE::Network::SDN::api_request(
+	    "DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers);
+    };
+    if ($@) {
+	die "error deleting ip $ip : $@" if !$noerr;
+    }
+}
+
+
+sub verify_api {
+    my ($class, $plugin_config) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+    # check that the namespace exists AND that default IP active status
+    # exists AND that we have indeed API access
+    eval {
+	get_namespace_id($url, $namespace, $headers, 0)
+	    // die "namespace $namespace does not exist";
+	get_status_id($url, default_ip_status(), $headers, 0)
+	    // die "default IP status ". default_ip_status() . " not found";
+    };
+    if ($@) {
+	die "Can't use nautobot api: $@";
+    }
+}
+
+sub get_ips_from_mac {
+    my ($class, $plugin_config, $mac) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+    my $ip4 = undef;
+    my $ip6 = undef;
+
+    my $data = PVE::Network::SDN::api_request(
+	"GET", "$url/ipam/ip-addresses/?q=$mac", $headers);
+    for my $ip (@{$data->{results}}) {
+	if ($ip->{ip_version} == 4 && !$ip4) {
+	    ($ip4, undef) = split(/\//, $ip->{address});
+	}
+
+	if ($ip->{ip_version} == 6 && !$ip6) {
+	    ($ip6, undef) = split(/\//, $ip->{address});
+	}
+    }
+
+    return ($ip4, $ip6);
+}
+
+sub on_update_hook {
+    my ($class, $plugin_config) = @_;
+
+    PVE::Network::SDN::Ipams::NautobotPlugin::verify_api(
+	$class, $plugin_config);
+}
+
+# helpers
+sub get_ips_within_range {
+    my ($start_address, $end_address, @list) = @_;
+    $start_address = NetAddr::IP->new($start_address);
+    $end_address = NetAddr::IP->new($end_address);
+    return grep($start_address <= NetAddr::IP->new($_) <= $end_address, @list);
+}
+
+sub get_ip_id {
+    my ($url, $ip, $headers, $noerr) = @_;
+
+    my $result = eval {
+	return PVE::Network::SDN::api_request(
+	    "GET", "$url/ipam/ip-addresses/?q=$ip", $headers);
+    };
+    if ($@) {
+	die "error while querying for ip $ip id: $@" if !$noerr;
+    }
+
+    my $data = @{$result->{results}}[0];
+    my $ip_id = $data->{id};
+    return $ip_id;
+}
+
+sub get_prefix_id {
+    my ($url, $cidr, $headers, $noerr) = @_;
+
+    my $result = eval {
+	return PVE::Network::SDN::api_request(
+	    "GET", "$url/ipam/prefixes/?q=$cidr", $headers);
+    };
+    if ($@) {
+	die "error while querying for cidr $cidr prefix id: $@" if !$noerr;
+    }
+
+    my $data = @{$result->{results}}[0];
+    my $internalid = $data->{id};
+    return $internalid;
+}
+
+sub get_namespace_id {
+    my ($url, $namespace, $headers, $noerr) = @_;
+
+    my $result = eval {
+	return PVE::Network::SDN::api_request(
+	    "GET", "$url/ipam/namespaces/?q=$namespace", $headers);
+    };
+    if ($@) {
+	die "error while querying for namespace $namespace id: $@" if !$noerr;
+    }
+
+    my $data = @{$result->{results}}[0];
+    my $internalid = $data->{id};
+    return $internalid;
+}
+
+sub get_status_id {
+    my ($url, $status, $headers, $noerr) = @_;
+
+    my $result = eval {
+	return PVE::Network::SDN::api_request(
+	    "GET", "$url/extras/statuses/?q=$status", $headers);
+    };
+    if ($@) {
+	die "error while querying for status $status id: $@" if !$noerr;
+    }
+
+    my $data = @{$result->{results}}[0];
+    my $internalid = $data->{id};
+    return $internalid;
+}
+
+sub is_ip_gateway {
+    my ($url, $ip, $headers, $noerr) = @_;
+
+    my $result = eval {
+	return PVE::Network::SDN::api_request(
+	    "GET", "$url/ipam/ip-addresses/?q=$ip", $headers);
+    };
+    if ($@) {
+	die "error while checking if $ip is a gateway" if !$noerr;
+    }
+
+    my $data = @{$result->{results}}[0];
+    my $description = $data->{description};
+    my $is_gateway = 0; $is_gateway = 1 if $description eq 'gateway';
+    return $is_gateway;
+}
+
+1;
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pve-devel] [PATCH pve-network v3 2/3] ipam: nautobot: add testing for nautobot plugin
       [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
  2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 1/3] ipam: nautobot: base plugin lou.lecrivain--- via pve-devel
@ 2025-03-06 11:08 ` lou.lecrivain--- via pve-devel
  2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 3/3] ipam: nautobot: add checks for prefix deletion lou.lecrivain--- via pve-devel
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: lou.lecrivain--- via pve-devel @ 2025-03-06 11:08 UTC (permalink / raw)
  To: pve-devel; +Cc: lou.lecrivain, jonatan.crystall

[-- Attachment #1: Type: message/rfc822, Size: 16672 bytes --]

From: lou.lecrivain@orange.fr
To: pve-devel@lists.proxmox.com
Cc: h.duerr@proxmox.com, jonatan.crystall@gwdg.de, Lou Lecrivain <lou.lecrivain@wdz.de>
Subject: [PATCH pve-network v3 2/3] ipam: nautobot: add testing for nautobot plugin
Date: Thu,  6 Mar 2025 12:08:30 +0100
Message-ID: <20250306110831.6426-3-lou.lecrivain@orange.fr>

From: Lou Lecrivain <lou.lecrivain@wdz.de>

Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm   | 29 +++++++++++++------
 src/test/ipams/nautobot/expected.add_ip       | 11 +++++++
 .../ipams/nautobot/expected.add_ip_notgateway | 11 +++++++
 .../ipams/nautobot/expected.add_next_freeip   | 11 +++++++
 src/test/ipams/nautobot/expected.add_subnet   | 11 +++++++
 src/test/ipams/nautobot/expected.del_ip       | 11 +++++++
 src/test/ipams/nautobot/expected.update_ip    | 11 +++++++
 src/test/ipams/nautobot/ipam_config           | 24 +++++++++++++++
 src/test/ipams/nautobot/sdn_config            | 20 +++++++++++++
 src/test/ipams/netbox/ipam_config             |  8 ++++-
 src/test/ipams/phpipam/ipam_config            |  8 ++++-
 11 files changed, 144 insertions(+), 11 deletions(-)
 create mode 100644 src/test/ipams/nautobot/expected.add_ip
 create mode 100644 src/test/ipams/nautobot/expected.add_ip_notgateway
 create mode 100644 src/test/ipams/nautobot/expected.add_next_freeip
 create mode 100644 src/test/ipams/nautobot/expected.add_subnet
 create mode 100644 src/test/ipams/nautobot/expected.del_ip
 create mode 100644 src/test/ipams/nautobot/expected.update_ip
 create mode 100644 src/test/ipams/nautobot/ipam_config
 create mode 100644 src/test/ipams/nautobot/sdn_config

diff --git a/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm b/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
index 58f7c68..6f2a380 100644
--- a/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
+++ b/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
@@ -54,7 +54,7 @@ sub add_subnet {
     my $namespace = $plugin_config->{namespace};
     my $headers = default_headers($plugin_config);
 
-    my $internalid = get_prefix_id($url, $cidr, $headers, $noerr);
+    my $internalid = get_prefix_id($plugin_config, $cidr, $noerr);
 
     #create subnet
     if (!$internalid) {
@@ -80,7 +80,7 @@ sub del_subnet {
     my $url = $plugin_config->{url};
     my $headers = default_headers($plugin_config);
 
-    my $internalid = get_prefix_id($url, $cidr, $headers, $noerr);
+    my $internalid = get_prefix_id($plugin_config, $cidr, $noerr);
     return if !$internalid;
 
     # TODO check that prefix is empty before deletion
@@ -142,7 +142,7 @@ sub add_next_freeip {
     my $namespace = $plugin_config->{namespace};
     my $headers = default_headers($plugin_config);
 
-    my $internalid = get_prefix_id($url, $cidr, $headers, $noerr);
+    my $internalid = get_prefix_id($plugin_config, $cidr, $noerr);
     die "cannot find prefix $cidr in Nautobot" if !$internalid;
 
     my $description = undef;
@@ -235,7 +235,7 @@ sub update_ip {
 	status => default_ip_status()
     };
 
-    my $ip_id = get_ip_id($url, $ip, $headers, $noerr);
+    my $ip_id = get_ip_id($plugin_config, $ip, $noerr);
     die "can't find ip $ip in ipam" if !$noerr && !$ip_id;
 
     eval {
@@ -256,7 +256,7 @@ sub del_ip {
     my $url = $plugin_config->{url};
     my $headers = default_headers($plugin_config);
 
-    my $ip_id = get_ip_id($url, $ip, $headers, $noerr);
+    my $ip_id = get_ip_id($plugin_config, $ip, $noerr);
     die "can't find ip $ip in ipam" if !$ip_id && !$noerr;
 
     eval {
@@ -268,7 +268,6 @@ sub del_ip {
     }
 }
 
-
 sub verify_api {
     my ($class, $plugin_config) = @_;
 
@@ -330,7 +329,11 @@ sub get_ips_within_range {
 }
 
 sub get_ip_id {
-    my ($url, $ip, $headers, $noerr) = @_;
+    my ($plugin_config, $ip, $noerr) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
 
     my $result = eval {
 	return PVE::Network::SDN::api_request(
@@ -346,7 +349,11 @@ sub get_ip_id {
 }
 
 sub get_prefix_id {
-    my ($url, $cidr, $headers, $noerr) = @_;
+    my ($plugin_config, $cidr, $noerr) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
 
     my $result = eval {
 	return PVE::Network::SDN::api_request(
@@ -394,7 +401,11 @@ sub get_status_id {
 }
 
 sub is_ip_gateway {
-    my ($url, $ip, $headers, $noerr) = @_;
+    my ($plugin_config, $ip, $noerr) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
 
     my $result = eval {
 	return PVE::Network::SDN::api_request(
diff --git a/src/test/ipams/nautobot/expected.add_ip b/src/test/ipams/nautobot/expected.add_ip
new file mode 100644
index 0000000..60c62d4
--- /dev/null
+++ b/src/test/ipams/nautobot/expected.add_ip
@@ -0,0 +1,11 @@
+bless( {
+                  '_content' => '{"address":"10.0.0.1/24","description":"gateway","dns_name":"myhostname","namespace":"TestNamespace","status":"Active","type":"dhcp"}',
+                  '_headers' => bless( {
+                                         'authorization' => 'token FAKETESTTOKEN',
+                                         'content-type' => 'application/json',
+					 'accept' => 'application/json'
+                                       }, 'HTTP::Headers' ),
+                  '_max_body_size' => undef,
+                  '_method' => 'POST',
+                  '_uri' => bless( do{\(my $o = 'http://localhost:8080/api/ipam/ip-addresses/')}, 'URI::http' )
+                }, 'HTTP::Request' );
diff --git a/src/test/ipams/nautobot/expected.add_ip_notgateway b/src/test/ipams/nautobot/expected.add_ip_notgateway
new file mode 100644
index 0000000..355ccde
--- /dev/null
+++ b/src/test/ipams/nautobot/expected.add_ip_notgateway
@@ -0,0 +1,11 @@
+bless( {
+                  '_content' => '{"address":"10.0.0.1/24","description":"mac:da:65:8f:18:9b:6f","dns_name":"myhostname","namespace":"TestNamespace","status":"Active","type":"dhcp"}',
+                  '_headers' => bless( {
+                                         'authorization' => 'token FAKETESTTOKEN',
+                                         'content-type' => 'application/json',
+					 'accept' => 'application/json'
+                                       }, 'HTTP::Headers' ),
+                  '_max_body_size' => undef,
+                  '_method' => 'POST',
+                  '_uri' => bless( do{\(my $o = 'http://localhost:8080/api/ipam/ip-addresses/')}, 'URI::http' )
+                }, 'HTTP::Request' );
diff --git a/src/test/ipams/nautobot/expected.add_next_freeip b/src/test/ipams/nautobot/expected.add_next_freeip
new file mode 100644
index 0000000..da79a27
--- /dev/null
+++ b/src/test/ipams/nautobot/expected.add_next_freeip
@@ -0,0 +1,11 @@
+bless( {
+                  '_content' => '{"description":"mac:da:65:8f:18:9b:6f","dns_name":"myhostname","namespace":"TestNamespace","status":"Active","type":"dhcp"}',
+                  '_headers' => bless( {
+                                         'authorization' => 'token FAKETESTTOKEN',
+                                         'content-type' => 'application/json',
+					 'accept' => 'application/json'
+                                       }, 'HTTP::Headers' ),
+                  '_max_body_size' => undef,
+                  '_method' => 'POST',
+                  '_uri' => bless( do{\(my $o = 'http://localhost:8080/api/ipam/prefixes/1/available-ips/')}, 'URI::http' )
+                }, 'HTTP::Request' );
diff --git a/src/test/ipams/nautobot/expected.add_subnet b/src/test/ipams/nautobot/expected.add_subnet
new file mode 100644
index 0000000..af4bc8e
--- /dev/null
+++ b/src/test/ipams/nautobot/expected.add_subnet
@@ -0,0 +1,11 @@
+bless({
+	'_content' => '{"namespace":"TestNamespace","prefix":"10.0.0.0/24","status":"Active"}',
+	'_headers' => bless({
+		   'authorization' => 'token FAKETESTTOKEN',
+		   'content-type' => 'application/json',
+		   'accept' => 'application/json',
+	}, 'HTTP::Headers'),
+	'_max_body_size' => undef,
+	'_method' => 'POST',
+	'_uri' => bless(do{\(my $o = 'http://localhost:8080/api/ipam/prefixes/')}, 'URI::http'),
+}, 'HTTP::Request');
diff --git a/src/test/ipams/nautobot/expected.del_ip b/src/test/ipams/nautobot/expected.del_ip
new file mode 100644
index 0000000..f4bc182
--- /dev/null
+++ b/src/test/ipams/nautobot/expected.del_ip
@@ -0,0 +1,11 @@
+bless( {
+                  '_content' => '',
+                  '_headers' => bless( {
+                                         'authorization' => 'token FAKETESTTOKEN',
+                                         'content-type' => 'application/json',
+					 'accept' => 'application/json'
+                                       }, 'HTTP::Headers' ),
+                  '_max_body_size' => undef,
+                  '_method' => 'DELETE',
+                  '_uri' => bless( do{\(my $o = 'http://localhost:8080/api/ipam/ip-addresses/1/')}, 'URI::http' )
+                }, 'HTTP::Request' );
diff --git a/src/test/ipams/nautobot/expected.update_ip b/src/test/ipams/nautobot/expected.update_ip
new file mode 100644
index 0000000..58e0ac6
--- /dev/null
+++ b/src/test/ipams/nautobot/expected.update_ip
@@ -0,0 +1,11 @@
+bless( {
+                  '_content' => '{"address":"10.0.0.1/24","description":"gateway","dns_name":"myhostname","namespace":"TestNamespace","status":"Active","type":"dhcp"}',
+                  '_headers' => bless( {
+                                         'authorization' => 'token FAKETESTTOKEN',
+                                         'content-type' => 'application/json',
+					 'accept' => 'application/json'
+                                       }, 'HTTP::Headers' ),
+                  '_max_body_size' => undef,
+                  '_method' => 'PATCH',
+                  '_uri' => bless( do{\(my $o = 'http://localhost:8080/api/ipam/ip-addresses/1/')}, 'URI::http' )
+                }, 'HTTP::Request' );
diff --git a/src/test/ipams/nautobot/ipam_config b/src/test/ipams/nautobot/ipam_config
new file mode 100644
index 0000000..014d6b1
--- /dev/null
+++ b/src/test/ipams/nautobot/ipam_config
@@ -0,0 +1,24 @@
+{
+          'ids' => {
+                     'phpipam' => {
+                                    'url' => 'https://localhost/api/apiadmin',
+                                    'type' => 'phpipam',
+                                    'section' => 1,
+                                    'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw'
+                                  },
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                     'netbox' => {
+                                   'token' => '0123456789abcdef0123456789abcdef01234567',
+                                   'type' => 'netbox',
+                                   'url' => 'http://localhost:8000/api'
+                                 },
+		      'nautobot' => {
+				    'url' => 'http://localhost:8080/api',
+				    'type' => 'nautobot',
+				    'token' => 'FAKETESTTOKEN',
+				    'namespace' => 'TestNamespace'
+		      }
+                   },
+}
diff --git a/src/test/ipams/nautobot/sdn_config b/src/test/ipams/nautobot/sdn_config
new file mode 100644
index 0000000..784cd95
--- /dev/null
+++ b/src/test/ipams/nautobot/sdn_config
@@ -0,0 +1,20 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                      },
+             },
+
+  zones   => {
+               ids => { myzone => { ipam => "nautobot" } },
+             },
+
+  subnets => {
+              ids => { 'myzone-10.0.0.0-24' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  }
+                     }
+             }
+}
diff --git a/src/test/ipams/netbox/ipam_config b/src/test/ipams/netbox/ipam_config
index a33be30..014d6b1 100644
--- a/src/test/ipams/netbox/ipam_config
+++ b/src/test/ipams/netbox/ipam_config
@@ -13,6 +13,12 @@
                                    'token' => '0123456789abcdef0123456789abcdef01234567',
                                    'type' => 'netbox',
                                    'url' => 'http://localhost:8000/api'
-                                 }
+                                 },
+		      'nautobot' => {
+				    'url' => 'http://localhost:8080/api',
+				    'type' => 'nautobot',
+				    'token' => 'FAKETESTTOKEN',
+				    'namespace' => 'TestNamespace'
+		      }
                    },
 }
diff --git a/src/test/ipams/phpipam/ipam_config b/src/test/ipams/phpipam/ipam_config
index a33be30..014d6b1 100644
--- a/src/test/ipams/phpipam/ipam_config
+++ b/src/test/ipams/phpipam/ipam_config
@@ -13,6 +13,12 @@
                                    'token' => '0123456789abcdef0123456789abcdef01234567',
                                    'type' => 'netbox',
                                    'url' => 'http://localhost:8000/api'
-                                 }
+                                 },
+		      'nautobot' => {
+				    'url' => 'http://localhost:8080/api',
+				    'type' => 'nautobot',
+				    'token' => 'FAKETESTTOKEN',
+				    'namespace' => 'TestNamespace'
+		      }
                    },
 }
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pve-devel] [PATCH pve-network v3 3/3] ipam: nautobot: add checks for prefix deletion
       [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
  2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 1/3] ipam: nautobot: base plugin lou.lecrivain--- via pve-devel
  2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 2/3] ipam: nautobot: add testing for nautobot plugin lou.lecrivain--- via pve-devel
@ 2025-03-06 11:08 ` lou.lecrivain--- via pve-devel
  2025-03-06 11:10 ` [pve-devel] [PATCH] pve-docs: add documentation for Nautobot IPAM plugin lou.lecrivain--- via pve-devel
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: lou.lecrivain--- via pve-devel @ 2025-03-06 11:08 UTC (permalink / raw)
  To: pve-devel; +Cc: lou.lecrivain, jonatan.crystall

[-- Attachment #1: Type: message/rfc822, Size: 6733 bytes --]

From: lou.lecrivain@orange.fr
To: pve-devel@lists.proxmox.com
Cc: h.duerr@proxmox.com, jonatan.crystall@gwdg.de, Lou Lecrivain <lou.lecrivain@wdz.de>
Subject: [PATCH pve-network v3 3/3] ipam: nautobot: add checks for prefix deletion
Date: Thu,  6 Mar 2025 12:08:31 +0100
Message-ID: <20250306110831.6426-4-lou.lecrivain@orange.fr>

From: Lou Lecrivain <lou.lecrivain@wdz.de>

check that prefix/subnet is empty (only gateway IPs should remain)
before deletion.

Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm | 73 ++++++++++++++++++++-
 1 file changed, 70 insertions(+), 3 deletions(-)

diff --git a/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm b/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
index 6f2a380..8096687 100644
--- a/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
+++ b/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
@@ -5,6 +5,7 @@ use warnings;
 use PVE::INotify;
 use PVE::Cluster;
 use PVE::Tools;
+use List::Util qw(all);
 use NetAddr::IP;
 
 use base('PVE::Network::SDN::Ipams::Plugin');
@@ -56,7 +57,7 @@ sub add_subnet {
 
     my $internalid = get_prefix_id($plugin_config, $cidr, $noerr);
 
-    #create subnet
+    #create subnet if it doesn't already exist
     if (!$internalid) {
 	my $params = {
 	    prefix => $cidr, namespace => $namespace,
@@ -83,8 +84,15 @@ sub del_subnet {
     my $internalid = get_prefix_id($plugin_config, $cidr, $noerr);
     return if !$internalid;
 
-    # TODO check that prefix is empty before deletion
-    return;
+    if (!subnet_is_deletable(
+	     $plugin_config, $subnetid, $subnet, $internalid, $noerr
+	)) {
+	die "cannot delete prefix $cidr, not empty!";
+    }
+
+    # delete associated IP addresses (normally should only be gateway IPs)
+    $class->empty_subnet(
+	$plugin_config, $subnetid, $subnet, $internalid, $noerr);
 
     eval {
 	PVE::Network::SDN::api_request(
@@ -268,6 +276,65 @@ sub del_ip {
     }
 }
 
+sub empty_subnet {
+    my ($class, $plugin_config, $subnetid, $subnet, $subnetuuid, $noerr) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+    my $response = eval {
+	return PVE::Network::SDN::api_request(
+	    "GET",
+	    "$url/ipam/ip-addresses/?namespace=$namespace&parent=$subnetuuid",
+	    $headers)
+    };
+    if ($@) {
+	die "error querying prefix $subnet: $@" if !$noerr;
+    }
+
+    for my $ip (@{$response->{results}}) {
+	del_ip($class, $plugin_config, $subnetid, $subnet, $ip->{host}, $noerr);
+    }
+}
+
+sub subnet_is_deletable {
+    my ($plugin_config, $subnetid, $subnet, $subnetuuid, $noerr) = @_;
+
+    my $url = $plugin_config->{url};
+    my $namespace = $plugin_config->{namespace};
+    my $headers = default_headers($plugin_config);
+
+
+    my $response = eval {
+	return PVE::Network::SDN::api_request(
+	    "GET",
+	    "$url/ipam/ip-addresses/?namespace=$namespace&parent=$subnetuuid",
+	    $headers)
+    };
+    if ($@) {
+	die "error querying prefix $subnet: $@" if !$noerr;
+    }
+    my $n_ips = scalar $response->{results}->@*;
+
+    # least costly check operation 1st
+    if ($n_ips == 0) {
+	# completely empty, delete ok
+	return 1;
+    } elsif (
+	!(all {$_ == 1} (
+	    map {
+		is_ip_gateway($plugin_config, $_->{host}, $noerr)
+	    } $response->{results}->@*
+	))) {
+	# some remaining IPs are not gateway, nok
+	return 0;
+    } else {
+	# remaining IPs are all gateway, delete ok
+	return 1;
+    }
+}
+
 sub verify_api {
     my ($class, $plugin_config) = @_;
 
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pve-devel] [PATCH] pve-docs: add documentation for Nautobot IPAM plugin
       [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
                   ` (2 preceding siblings ...)
  2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 3/3] ipam: nautobot: add checks for prefix deletion lou.lecrivain--- via pve-devel
@ 2025-03-06 11:10 ` lou.lecrivain--- via pve-devel
  2025-03-06 11:10 ` [pve-devel] [PATCH] pve-manager: add UI dialogs for Nautobot IPAM backend lou.lecrivain--- via pve-devel
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: lou.lecrivain--- via pve-devel @ 2025-03-06 11:10 UTC (permalink / raw)
  To: pve-devel; +Cc: lou.lecrivain, Jonatan Crystall

[-- Attachment #1: Type: message/rfc822, Size: 4591 bytes --]

From: lou.lecrivain@orange.fr
To: pve-devel@lists.proxmox.com
Cc: h.duerr@proxmox.com, Jonatan Crystall <jonatan.crystall@gwdg.de>, lou lecrivain <lou.lecrivain@wdz.de>
Subject: [PATCH] pve-docs: add documentation for Nautobot IPAM plugin
Date: Thu,  6 Mar 2025 12:10:08 +0100
Message-ID: <20250306111008.6538-1-lou.lecrivain@orange.fr>

From: Jonatan Crystall <jonatan.crystall@gwdg.de>

Co-authored-by: Jonatan Crystall <jonatan.crystall@gwdg.de>
Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 pvesdn.adoc | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/pvesdn.adoc b/pvesdn.adoc
index 5d5d27b..d4744ab 100644
--- a/pvesdn.adoc
+++ b/pvesdn.adoc
@@ -561,6 +561,25 @@ URL:: The NetBox REST API endpoint: `http://yournetbox.domain.com/api`
 
 Token:: An API access token
 
+[[pvesdn_ipam_plugin_nautobot]]
+Nautobot IPAM Plugin
+~~~~~~~~~~~~~~~~~~
+
+link:https://github.com/nautobot/nautobot[Nautobot] is an open-source IP
+Address Management (IPAM) and datacenter infrastructure management (DCIM) tool.
+
+To integrate Nautobot with {pve} SDN, create an API token in Nautobot as described
+here:
+https://docs.nautobot.com/projects/core/en/stable/user-guide/platform-functionality/users/token/
+
+The Nautobot configuration properties are:
+
+URL:: The Nautobot REST API endpoint: `http://yournautobot.domain.com/api`
+
+Token:: An API access token
+
+Namespace:: Nautobot IP Namespace 
+
 
 [[pvesdn_ipam_plugin_phpipam]]
 phpIPAM Plugin
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pve-devel] [PATCH] pve-manager: add UI dialogs for Nautobot IPAM backend
       [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
                   ` (3 preceding siblings ...)
  2025-03-06 11:10 ` [pve-devel] [PATCH] pve-docs: add documentation for Nautobot IPAM plugin lou.lecrivain--- via pve-devel
@ 2025-03-06 11:10 ` lou.lecrivain--- via pve-devel
  2025-03-06 12:13 ` [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support Hannes Dürr
  2025-03-06 12:18 ` Hannes Dürr
  6 siblings, 0 replies; 9+ messages in thread
From: lou.lecrivain--- via pve-devel @ 2025-03-06 11:10 UTC (permalink / raw)
  To: pve-devel; +Cc: lou.lecrivain, Jonatan Crystall

[-- Attachment #1: Type: message/rfc822, Size: 5881 bytes --]

From: lou.lecrivain@orange.fr
To: pve-devel@lists.proxmox.com
Cc: h.duerr@proxmox.com, Jonatan Crystall <jonatan.crystall@gwdg.de>, Lou Lecrivain <lou.lecrivain@wdz.de>
Subject: [PATCH] pve-manager: add UI dialogs for Nautobot IPAM backend
Date: Thu,  6 Mar 2025 12:10:41 +0100
Message-ID: <20250306111041.6597-1-lou.lecrivain@orange.fr>

From: Jonatan Crystall <jonatan.crystall@gwdg.de>

Co-authored-by: Jonatan Crystall <jonatan.crystall@gwdg.de>
Signed-off-by: Lou Lecrivain <lou.lecrivain@wdz.de>
---
 www/manager6/Makefile                  |  1 +
 www/manager6/Utils.js                  |  5 +++
 www/manager6/sdn/ipams/NautobotEdit.js | 52 ++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)
 create mode 100644 www/manager6/sdn/ipams/NautobotEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index c94a5cdf..aee431ae 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -292,6 +292,7 @@ JSSRC= 							\
 	sdn/IpamView.js					\
 	sdn/ipams/Base.js				\
 	sdn/ipams/NetboxEdit.js				\
+	sdn/ipams/NautobotEdit.js				\
 	sdn/ipams/PVEIpamEdit.js			\
 	sdn/ipams/PhpIpamEdit.js			\
 	sdn/DnsView.js					\
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index 90011a8f..338039b5 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -931,6 +931,11 @@ Ext.define('PVE.Utils', {
 	    ipanel: 'PhpIpamInputPanel',
 	    faIcon: 'th',
 	},
+	nautobot: {
+	    name: 'Nautobot',
+	    ipanel: 'NautobotInputPanel',
+	    faIcon: 'th',
+	},
     },
 
     sdndnsSchema: {
diff --git a/www/manager6/sdn/ipams/NautobotEdit.js b/www/manager6/sdn/ipams/NautobotEdit.js
new file mode 100644
index 00000000..06d8f2c8
--- /dev/null
+++ b/www/manager6/sdn/ipams/NautobotEdit.js
@@ -0,0 +1,52 @@
+Ext.define('PVE.sdn.ipams.NautobotInputPanel', {
+    extend: 'PVE.panel.SDNIpamBase',
+
+    onlineHelp: 'pvesdn_ipam_plugin_nautobot', // TODO: update docs
+
+    onGetValues: function(values) {
+        var me = this;
+
+	if (me.isCreate) {
+	    values.type = me.type;
+	} else {
+	    delete values.ipam;
+	}
+
+	return values;
+    },
+
+    initComponent: function() {
+	var me = this;
+
+	me.items = [
+	    {
+		xtype: me.isCreate ? 'textfield' : 'displayfield',
+		name: 'ipam',
+		maxLength: 10,
+		value: me.zone || '',
+		fieldLabel: 'ID',
+		allowBlank: false,
+	    },
+	    {
+		xtype: 'textfield',
+		name: 'url',
+		fieldLabel: gettext('URL'),
+		allowBlank: false,
+	    },
+	    {
+		xtype: 'textfield',
+		name: 'token',
+		fieldLabel: gettext('Token'),
+		allowBlank: false,
+	    },
+		{
+		xtype: 'textfield',
+		name: 'namespace',
+		fieldLabel: gettext('Namespace'),
+		allowBlank: false,
+		},
+	];
+
+	me.callParent();
+    },
+});
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support
       [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
                   ` (4 preceding siblings ...)
  2025-03-06 11:10 ` [pve-devel] [PATCH] pve-manager: add UI dialogs for Nautobot IPAM backend lou.lecrivain--- via pve-devel
@ 2025-03-06 12:13 ` Hannes Dürr
  2025-03-06 13:11   ` Lou Lecrivain via pve-devel
       [not found]   ` <FR3PPF52E80A3568CB02FD718D9A4A750B885CA2@FR3PPF52E80A356.DEUP281.PROD.OUTLOOK.COM>
  2025-03-06 12:18 ` Hannes Dürr
  6 siblings, 2 replies; 9+ messages in thread
From: Hannes Dürr @ 2025-03-06 12:13 UTC (permalink / raw)
  To: lou.lecrivain, pve-devel; +Cc: jonatan.crystall

Hi,

and thanks to the both of you!

Can you please resend the mail to our mailing list so that it is 
available for everyone please?
Another tiny thing, we don't use "From: Lou Lecrivain 
<lou.lecrivain@wdz.de>" but "Signed-off-by: Lou Lecrivain 
<lou.lecrivain@wdz.de>"
which indicates that contribution was created in whole or in part by 
yourself and you have the right to submit it under our open source license.
jonathan crystall can use the "Co-developed-by: Jonatan Crystall 
<jonatan.crystall@gwdg.de>" to make it clear that he contributed the code.

Best wishes,
Hannes Dürr

On 3/6/25 12:08, lou.lecrivain@orange.fr wrote:
> From: Lou Lecrivain <lou.lecrivain@wdz.de>
>
> Following review from Hannes,
>
> I have made some improvements to the form of the code for the pve-network part.
> No functional changes.
>
> Related changes to pve-manager and pve-docs are also included the email thread.
>
> BR
>
> Lou Lecrivain (3):
>    ipam: nautobot: base plugin
>    ipam: nautobot: add testing for nautobot plugin
>    ipam: nautobot: add checks for prefix deletion
>
>   src/PVE/API2/Network/SDN/Ipams.pm             |   1 +
>   src/PVE/Network/SDN/Ipams.pm                  |   3 +
>   src/PVE/Network/SDN/Ipams/Makefile            |   2 +-
>   src/PVE/Network/SDN/Ipams/NautobotPlugin.pm   | 491 ++++++++++++++++++
>   src/test/ipams/nautobot/expected.add_ip       |  11 +
>   .../ipams/nautobot/expected.add_ip_notgateway |  11 +
>   .../ipams/nautobot/expected.add_next_freeip   |  11 +
>   src/test/ipams/nautobot/expected.add_subnet   |  11 +
>   src/test/ipams/nautobot/expected.del_ip       |  11 +
>   src/test/ipams/nautobot/expected.update_ip    |  11 +
>   src/test/ipams/nautobot/ipam_config           |  24 +
>   src/test/ipams/nautobot/sdn_config            |  20 +
>   src/test/ipams/netbox/ipam_config             |   8 +-
>   src/test/ipams/phpipam/ipam_config            |   8 +-
>   14 files changed, 620 insertions(+), 3 deletions(-)
>   create mode 100644 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
>   create mode 100644 src/test/ipams/nautobot/expected.add_ip
>   create mode 100644 src/test/ipams/nautobot/expected.add_ip_notgateway
>   create mode 100644 src/test/ipams/nautobot/expected.add_next_freeip
>   create mode 100644 src/test/ipams/nautobot/expected.add_subnet
>   create mode 100644 src/test/ipams/nautobot/expected.del_ip
>   create mode 100644 src/test/ipams/nautobot/expected.update_ip
>   create mode 100644 src/test/ipams/nautobot/ipam_config
>   create mode 100644 src/test/ipams/nautobot/sdn_config
>


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support
       [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
                   ` (5 preceding siblings ...)
  2025-03-06 12:13 ` [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support Hannes Dürr
@ 2025-03-06 12:18 ` Hannes Dürr
  6 siblings, 0 replies; 9+ messages in thread
From: Hannes Dürr @ 2025-03-06 12:18 UTC (permalink / raw)
  To: lou.lecrivain, pve-devel; +Cc: jonatan.crystall

sorry my mistake, it looked to me as if the mail did not go to the 
mailing list, but it did.

On 3/6/25 12:08, lou.lecrivain@orange.fr wrote:
> From: Lou Lecrivain <lou.lecrivain@wdz.de>
>
> Following review from Hannes,
>
> I have made some improvements to the form of the code for the pve-network part.
> No functional changes.
>
> Related changes to pve-manager and pve-docs are also included the email thread.
>
> BR
>
> Lou Lecrivain (3):
>    ipam: nautobot: base plugin
>    ipam: nautobot: add testing for nautobot plugin
>    ipam: nautobot: add checks for prefix deletion
>
>   src/PVE/API2/Network/SDN/Ipams.pm             |   1 +
>   src/PVE/Network/SDN/Ipams.pm                  |   3 +
>   src/PVE/Network/SDN/Ipams/Makefile            |   2 +-
>   src/PVE/Network/SDN/Ipams/NautobotPlugin.pm   | 491 ++++++++++++++++++
>   src/test/ipams/nautobot/expected.add_ip       |  11 +
>   .../ipams/nautobot/expected.add_ip_notgateway |  11 +
>   .../ipams/nautobot/expected.add_next_freeip   |  11 +
>   src/test/ipams/nautobot/expected.add_subnet   |  11 +
>   src/test/ipams/nautobot/expected.del_ip       |  11 +
>   src/test/ipams/nautobot/expected.update_ip    |  11 +
>   src/test/ipams/nautobot/ipam_config           |  24 +
>   src/test/ipams/nautobot/sdn_config            |  20 +
>   src/test/ipams/netbox/ipam_config             |   8 +-
>   src/test/ipams/phpipam/ipam_config            |   8 +-
>   14 files changed, 620 insertions(+), 3 deletions(-)
>   create mode 100644 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
>   create mode 100644 src/test/ipams/nautobot/expected.add_ip
>   create mode 100644 src/test/ipams/nautobot/expected.add_ip_notgateway
>   create mode 100644 src/test/ipams/nautobot/expected.add_next_freeip
>   create mode 100644 src/test/ipams/nautobot/expected.add_subnet
>   create mode 100644 src/test/ipams/nautobot/expected.del_ip
>   create mode 100644 src/test/ipams/nautobot/expected.update_ip
>   create mode 100644 src/test/ipams/nautobot/ipam_config
>   create mode 100644 src/test/ipams/nautobot/sdn_config
>


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support
  2025-03-06 12:13 ` [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support Hannes Dürr
@ 2025-03-06 13:11   ` Lou Lecrivain via pve-devel
       [not found]   ` <FR3PPF52E80A3568CB02FD718D9A4A750B885CA2@FR3PPF52E80A356.DEUP281.PROD.OUTLOOK.COM>
  1 sibling, 0 replies; 9+ messages in thread
From: Lou Lecrivain via pve-devel @ 2025-03-06 13:11 UTC (permalink / raw)
  To: h.duerr, pve-devel; +Cc: Lou.Lecrivain, jonatan.crystall

[-- Attachment #1: Type: message/rfc822, Size: 15051 bytes --]

From: <Lou.Lecrivain@wdz.de>
To: <h.duerr@proxmox.com>, <pve-devel@lists.proxmox.com>
Cc: <jonatan.crystall@gwdg.de>
Subject: RE:  Re: [PATCH-SERIES pve-network v3] Add Nautobot IPAM support
Date: Thu, 6 Mar 2025 13:11:10 +0000
Message-ID: <FR3PPF52E80A3568CB02FD718D9A4A750B885CA2@FR3PPF52E80A356.DEUP281.PROD.OUTLOOK.COM>

Re Hannes,

You're welcome :)

Sorry for the "from:", my mistake, must've slipped through before sending the patches.... (I may have forgot to signoff).
Noted for the Co-developed-by.

Would it be OK for you to edit that in or do I have to resend the patch series?

MfG
________________________________________
De : Hannes Dürr <h.duerr@proxmox.com>
Envoyé : jeudi 6 mars 2025 13:13
À : lou.lecrivain@orange.fr <lou.lecrivain@orange.fr>; pve-devel@lists.proxmox.com <pve-devel@lists.proxmox.com>
Cc : jonatan.crystall@gwdg.de <jonatan.crystall@gwdg.de>; Lecrivain, Lou (WDZ) <Lou.Lecrivain@wdz.de>
Objet : [!!ACHTUNG extern!!] - Re: [PATCH-SERIES pve-network v3] Add Nautobot IPAM support
 
Hi,

and thanks to the both of you!

Can you please resend the mail to our mailing list so that it is
available for everyone please?
Another tiny thing, we don't use "From: Lou Lecrivain
<lou.lecrivain@wdz.de>" but "Signed-off-by: Lou Lecrivain
<lou.lecrivain@wdz.de>"
which indicates that contribution was created in whole or in part by
yourself and you have the right to submit it under our open source license.
jonathan crystall can use the "Co-developed-by: Jonatan Crystall
<jonatan.crystall@gwdg.de>" to make it clear that he contributed the code.

Best wishes,
Hannes Dürr

On 3/6/25 12:08, lou.lecrivain@orange.fr wrote:
> From: Lou Lecrivain <lou.lecrivain@wdz.de>
>
> Following review from Hannes,
>
> I have made some improvements to the form of the code for the pve-network part.
> No functional changes.
>
> Related changes to pve-manager and pve-docs are also included the email thread.
>
> BR
>
> Lou Lecrivain (3):
>    ipam: nautobot: base plugin
>    ipam: nautobot: add testing for nautobot plugin
>    ipam: nautobot: add checks for prefix deletion
>
>   src/PVE/API2/Network/SDN/Ipams.pm             |   1 +
>   src/PVE/Network/SDN/Ipams.pm                  |   3 +
>   src/PVE/Network/SDN/Ipams/Makefile            |   2 +-
>   src/PVE/Network/SDN/Ipams/NautobotPlugin.pm   | 491 ++++++++++++++++++
>   src/test/ipams/nautobot/expected.add_ip       |  11 +
>   .../ipams/nautobot/expected.add_ip_notgateway |  11 +
>   .../ipams/nautobot/expected.add_next_freeip   |  11 +
>   src/test/ipams/nautobot/expected.add_subnet   |  11 +
>   src/test/ipams/nautobot/expected.del_ip       |  11 +
>   src/test/ipams/nautobot/expected.update_ip    |  11 +
>   src/test/ipams/nautobot/ipam_config           |  24 +
>   src/test/ipams/nautobot/sdn_config            |  20 +
>   src/test/ipams/netbox/ipam_config             |   8 +-
>   src/test/ipams/phpipam/ipam_config            |   8 +-
>   14 files changed, 620 insertions(+), 3 deletions(-)
>   create mode 100644 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
>   create mode 100644 src/test/ipams/nautobot/expected.add_ip
>   create mode 100644 src/test/ipams/nautobot/expected.add_ip_notgateway
>   create mode 100644 src/test/ipams/nautobot/expected.add_next_freeip
>   create mode 100644 src/test/ipams/nautobot/expected.add_subnet
>   create mode 100644 src/test/ipams/nautobot/expected.del_ip
>   create mode 100644 src/test/ipams/nautobot/expected.update_ip
>   create mode 100644 src/test/ipams/nautobot/ipam_config
>   create mode 100644 src/test/ipams/nautobot/sdn_config
>


[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support
       [not found]   ` <FR3PPF52E80A3568CB02FD718D9A4A750B885CA2@FR3PPF52E80A356.DEUP281.PROD.OUTLOOK.COM>
@ 2025-03-06 13:14     ` Hannes Dürr
  0 siblings, 0 replies; 9+ messages in thread
From: Hannes Dürr @ 2025-03-06 13:14 UTC (permalink / raw)
  To: Lou.Lecrivain, pve-devel; +Cc: jonatan.crystall

I will review and test the series and then you can add it to the next 
version if necessary. Otherwise we can also edit it.

On 3/6/25 14:11, Lou.Lecrivain@wdz.de wrote:
> Re Hannes,
>
> You're welcome :)
>
> Sorry for the "from:", my mistake, must've slipped through before sending the patches.... (I may have forgot to signoff).
> Noted for the Co-developed-by.
>
> Would it be OK for you to edit that in or do I have to resend the patch series?
>
> MfG
> ________________________________________
> De : Hannes Dürr <h.duerr@proxmox.com>
> Envoyé : jeudi 6 mars 2025 13:13
> À : lou.lecrivain@orange.fr <lou.lecrivain@orange.fr>; pve-devel@lists.proxmox.com <pve-devel@lists.proxmox.com>
> Cc : jonatan.crystall@gwdg.de <jonatan.crystall@gwdg.de>; Lecrivain, Lou (WDZ) <Lou.Lecrivain@wdz.de>
> Objet : [!!ACHTUNG extern!!] - Re: [PATCH-SERIES pve-network v3] Add Nautobot IPAM support
>   
> Hi,
>
> and thanks to the both of you!
>
> Can you please resend the mail to our mailing list so that it is
> available for everyone please?
> Another tiny thing, we don't use "From: Lou Lecrivain
> <lou.lecrivain@wdz.de>" but "Signed-off-by: Lou Lecrivain
> <lou.lecrivain@wdz.de>"
> which indicates that contribution was created in whole or in part by
> yourself and you have the right to submit it under our open source license.
> jonathan crystall can use the "Co-developed-by: Jonatan Crystall
> <jonatan.crystall@gwdg.de>" to make it clear that he contributed the code.
>
> Best wishes,
> Hannes Dürr
>
> On 3/6/25 12:08, lou.lecrivain@orange.fr wrote:
>> From: Lou Lecrivain <lou.lecrivain@wdz.de>
>>
>> Following review from Hannes,
>>
>> I have made some improvements to the form of the code for the pve-network part.
>> No functional changes.
>>
>> Related changes to pve-manager and pve-docs are also included the email thread.
>>
>> BR
>>
>> Lou Lecrivain (3):
>>      ipam: nautobot: base plugin
>>      ipam: nautobot: add testing for nautobot plugin
>>      ipam: nautobot: add checks for prefix deletion
>>
>>     src/PVE/API2/Network/SDN/Ipams.pm             |   1 +
>>     src/PVE/Network/SDN/Ipams.pm                  |   3 +
>>     src/PVE/Network/SDN/Ipams/Makefile            |   2 +-
>>     src/PVE/Network/SDN/Ipams/NautobotPlugin.pm   | 491 ++++++++++++++++++
>>     src/test/ipams/nautobot/expected.add_ip       |  11 +
>>     .../ipams/nautobot/expected.add_ip_notgateway |  11 +
>>     .../ipams/nautobot/expected.add_next_freeip   |  11 +
>>     src/test/ipams/nautobot/expected.add_subnet   |  11 +
>>     src/test/ipams/nautobot/expected.del_ip       |  11 +
>>     src/test/ipams/nautobot/expected.update_ip    |  11 +
>>     src/test/ipams/nautobot/ipam_config           |  24 +
>>     src/test/ipams/nautobot/sdn_config            |  20 +
>>     src/test/ipams/netbox/ipam_config             |   8 +-
>>     src/test/ipams/phpipam/ipam_config            |   8 +-
>>     14 files changed, 620 insertions(+), 3 deletions(-)
>>     create mode 100644 src/PVE/Network/SDN/Ipams/NautobotPlugin.pm
>>     create mode 100644 src/test/ipams/nautobot/expected.add_ip
>>     create mode 100644 src/test/ipams/nautobot/expected.add_ip_notgateway
>>     create mode 100644 src/test/ipams/nautobot/expected.add_next_freeip
>>     create mode 100644 src/test/ipams/nautobot/expected.add_subnet
>>     create mode 100644 src/test/ipams/nautobot/expected.del_ip
>>     create mode 100644 src/test/ipams/nautobot/expected.update_ip
>>     create mode 100644 src/test/ipams/nautobot/ipam_config
>>     create mode 100644 src/test/ipams/nautobot/sdn_config
>>


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-03-06 13:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20250306110831.6426-1-lou.lecrivain@orange.fr>
2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 1/3] ipam: nautobot: base plugin lou.lecrivain--- via pve-devel
2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 2/3] ipam: nautobot: add testing for nautobot plugin lou.lecrivain--- via pve-devel
2025-03-06 11:08 ` [pve-devel] [PATCH pve-network v3 3/3] ipam: nautobot: add checks for prefix deletion lou.lecrivain--- via pve-devel
2025-03-06 11:10 ` [pve-devel] [PATCH] pve-docs: add documentation for Nautobot IPAM plugin lou.lecrivain--- via pve-devel
2025-03-06 11:10 ` [pve-devel] [PATCH] pve-manager: add UI dialogs for Nautobot IPAM backend lou.lecrivain--- via pve-devel
2025-03-06 12:13 ` [pve-devel] [PATCH-SERIES pve-network v3] Add Nautobot IPAM support Hannes Dürr
2025-03-06 13:11   ` Lou Lecrivain via pve-devel
     [not found]   ` <FR3PPF52E80A3568CB02FD718D9A4A750B885CA2@FR3PPF52E80A356.DEUP281.PROD.OUTLOOK.COM>
2025-03-06 13:14     ` Hannes Dürr
2025-03-06 12:18 ` Hannes Dürr

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