[pve-devel] SPAM: [PATCH pve-network v2 1/7] ipam: nautobot support initial commit
Hannes Dürr
h.duerr at proxmox.com
Wed Feb 19 17:36:57 CET 2025
On 1/8/25 13:15, Lou Lecrivain via pve-devel wrote:
> +use base('PVE::Network::SDN::Ipams::NetboxPlugin'); why do you base the Plugin in NetboxPlugin at the beginning?> +sub
get_ips_from_mac { > + my ($class, $plugin_config, $mac, $zoneid) = @_;
$zoneid is unused in the function, this looks like a copy paste mistake
On 1/8/25 13:15, Lou Lecrivain via pve-devel wrote:
> This is the initial Nautobot plugin, based on the Netbox plugin
> implementation. Signed-off-by: lou lecrivain <lou.lecrivain at 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 | 195 ++++++++++++++++++++
> 4 files changed, 200 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..69e7897 --- /dev/null +++
> b/src/PVE/Network/SDN/Ipams/NautobotPlugin.pm @@ -0,0 +1,195 @@
> +package PVE::Network::SDN::Ipams::NautobotPlugin; + +use strict; +use
> warnings; +use PVE::INotify; +use PVE::Cluster; +use PVE::Tools; +
> +use base('PVE::Network::SDN::Ipams::NetboxPlugin');
why do you base the Plugin in NetboxPlugin at the beginning?
> + +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, $subnetid, $subnet, $noerr) = @_;
$subnetid is unused
> + + 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 =
> PVE::Network::SDN::Ipams::NetboxPlugin::get_prefix_id($url, $cidr,
> $headers); + + #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 add_ip { + my ($class,
> $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $vmid,
> $is_gateway, $noerr) = @_;
$subnetid and $vmid are unused
> + + 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()};
please break the line
> + + 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
> !PVE::Network::SDN::Ipams::NetboxPlugin::is_ip_gateway($url, $ip,
> $headers) && !$noerr; + } else { + die "error adding subnet ip to
> ipam: ip $ip already exists: $@" if !$noerr; + } + } +} + + +sub
> update_ip { + my ($class, $plugin_config, $subnetid, $subnet, $ip,
> $hostname, $mac, $vmid, $is_gateway, $noerr) = @_;
$vmid is unused
> + + 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 =
> PVE::Network::SDN::Ipams::NetboxPlugin::get_ip_id($url, $ip,
> $headers); + die "can't find ip $ip in ipam" if !$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
> verify_api { + my ($class, $plugin_config) = @_;
$class is unused
> + + 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) //
> die "namespace $namespace does not exist"; + get_status_id($url,
> default_ip_status(), $headers) // 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, $zoneid) = @_;
$zoneid is unused in the function, this looks like a copy paste mistake
> + + 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_namespace_id { + my ($url,
> $namespace, $headers) = @_; + + my $result =
> PVE::Network::SDN::api_request("GET",
> "$url/ipam/namespaces/?q=$namespace", $headers); + my $data =
> @{$result->{results}}[0]; + my $internalid = $data->{id}; + return
> $internalid; +} + +sub get_status_id { + my ($url, $status, $headers)
> = @_; + + my $result = PVE::Network::SDN::api_request("GET",
> "$url/extras/statuses/?q=$status", $headers); + my $data =
> @{$result->{results}}[0]; + my $internalid = $data->{id}; + return
> $internalid; +} + +1;
> -- 2.39.5 ______________________________________________
> pve-devel mailing list
> pve-devel at lists.proxmox.comhttps://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
More information about the pve-devel
mailing list