From: Hannes Duerr Date: Mon, 10 Feb 2025 14:19:29 +0000 (+0100) Subject: ipam: netbox integration: add fingerprint option to api requests X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=3903003f313efb6da79e5c508e65c94441a9affd;p=matthieu%2Fpve-network.git ipam: netbox integration: add fingerprint option to api requests Signed-off-by: Hannes Duerr Tested-by: Stefan Hanreich Signed-off-by: Thomas Lamprecht --- diff --git a/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm index d923269..18089b7 100644 --- a/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm +++ b/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm @@ -18,10 +18,10 @@ sub properties { } sub options { - return { url => { optional => 0}, token => { optional => 0 }, + fingerprint => { optional => 1 }, }; } @@ -34,9 +34,10 @@ sub add_subnet { my $gateway = $subnet->{gateway}; my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; + my $fingerprint = $plugin_config->{fingerprint}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; - my $internalid = get_prefix_id($url, $cidr, $headers); + my $internalid = get_prefix_id($url, $cidr, $headers, $fingerprint); #create subnet if (!$internalid) { @@ -44,7 +45,8 @@ sub add_subnet { my $params = { prefix => $cidr }; eval { - my $result = PVE::Network::SDN::api_request("POST", "$url/ipam/prefixes/", $headers, $params); + my $result = PVE::Network::SDN::api_request( + "POST", "$url/ipam/prefixes/", $headers, $params, $fingerprint ); }; if ($@) { die "error add subnet to ipam: $@" if !$noerr; @@ -60,15 +62,17 @@ sub del_subnet { my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; my $gateway = $subnet->{gateway}; + my $fingerprint = $plugin_config->{fingerprint}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; - my $internalid = get_prefix_id($url, $cidr, $headers); + my $internalid = get_prefix_id($url, $cidr, $headers, $fingerprint); return if !$internalid; return; #fixme: check that prefix is empty exluding gateway, before delete eval { - PVE::Network::SDN::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers); + PVE::Network::SDN::api_request( + "DELETE", "$url/ipam/prefixes/$internalid/", $headers, undef, $fingerprint); }; if ($@) { die "error deleting subnet from ipam: $@" if !$noerr; @@ -82,7 +86,7 @@ sub add_ip { my $mask = $subnet->{mask}; my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; - my $section = $plugin_config->{section}; + my $fingerprint = $plugin_config->{fingerprint}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; my $description = undef; @@ -95,14 +99,17 @@ sub add_ip { my $params = { address => "$ip/$mask", dns_name => $hostname, description => $description }; eval { - PVE::Network::SDN::api_request("POST", "$url/ipam/ip-addresses/", $headers, $params); + PVE::Network::SDN::api_request( + "POST", "$url/ipam/ip-addresses/", $headers, $params, $fingerprint); }; if ($@) { - if($is_gateway) { - die "error add subnet ip to ipam: ip $ip already exist: $@" if !is_ip_gateway($url, $ip, $headers) && !$noerr; - } else { - die "error add subnet ip to ipam: ip already exist: $@" if !$noerr; + if ($is_gateway) { + if (!is_ip_gateway($url, $ip, $headers, $fingerprint) && !$noerr) { + die "error add subnet ip to ipam: ip $ip already exist: $@"; + } + } elsif (!$noerr) { + die "error add subnet ip to ipam: ip already exist: $@"; } } } @@ -114,6 +121,7 @@ sub update_ip { my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; my $section = $plugin_config->{section}; + my $fingerprint = $plugin_config->{fingerprint}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; my $description = undef; @@ -125,11 +133,12 @@ sub update_ip { my $params = { address => "$ip/$mask", dns_name => $hostname, description => $description }; - my $ip_id = get_ip_id($url, $ip, $headers); + my $ip_id = get_ip_id($url, $ip, $headers, $fingerprint); 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); + PVE::Network::SDN::api_request( + "PATCH", "$url/ipam/ip-addresses/$ip_id/", $headers, $params, $fingerprint); }; if ($@) { die "error update ip $ip : $@" if !$noerr; @@ -143,16 +152,18 @@ sub add_next_freeip { my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; + my $fingerprint = $plugin_config->{fingerprint}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; - my $internalid = get_prefix_id($url, $cidr, $headers); + my $internalid = get_prefix_id($url, $cidr, $headers, $fingerprint); my $description = "mac:$mac" if $mac; my $params = { dns_name => $hostname, description => $description }; eval { - my $result = PVE::Network::SDN::api_request("POST", "$url/ipam/prefixes/$internalid/available-ips/", $headers, $params); + my $result = PVE::Network::SDN::api_request( + "POST", "$url/ipam/prefixes/$internalid/available-ips/", $headers, $params, $fingerprint); my ($ip, undef) = split(/\//, $result->{address}); return $ip; }; @@ -168,14 +179,16 @@ sub add_range_next_freeip { my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; + my $fingerprint = $plugin_config->{fingerprint}; - my $internalid = get_iprange_id($url, $range, $headers); + my $internalid = get_iprange_id($url, $range, $headers, $fingerprint); my $description = "mac:$data->{mac}" if $data->{mac}; my $params = { dns_name => $data->{hostname}, description => $description }; eval { - my $result = PVE::Network::SDN::api_request("POST", "$url/ipam/ip-ranges/$internalid/available-ips/", $headers, $params); + my $result = PVE::Network::SDN::api_request( + "POST", "$url/ipam/ip-ranges/$internalid/available-ips/", $headers, $params, $fingerprint); my ($ip, undef) = split(/\//, $result->{address}); print "found ip free $ip in range $range->{'start-address'}-$range->{'end-address'}\n" if $ip; return $ip; @@ -194,12 +207,13 @@ sub del_ip { my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; + my $fingerprint = $plugin_config->{fingerprint}; - my $ip_id = get_ip_id($url, $ip, $headers); + my $ip_id = get_ip_id($url, $ip, $headers, $fingerprint); die "can't find ip $ip in ipam" if !$ip_id; eval { - PVE::Network::SDN::api_request("DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers); + PVE::Network::SDN::api_request("DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers, undef, $fingerprint); }; if ($@) { die "error delete ip $ip : $@" if !$noerr; @@ -212,11 +226,14 @@ sub get_ips_from_mac { my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; + my $fingerprint = $plugin_config->{fingerprint}; my $ip4 = undef; my $ip6 = undef; - my $data = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-addresses/?description__ic=$mac", $headers); + my $data = PVE::Network::SDN::api_request( + "GET", "$url/ipam/ip-addresses/?description__ic=$mac", $headers, undef, $fingerprint); + for my $ip (@{$data->{results}}) { if ($ip->{family}->{value} == 4 && !$ip4) { ($ip4, undef) = split(/\//, $ip->{address}); @@ -237,10 +254,10 @@ sub verify_api { my $url = $plugin_config->{url}; my $token = $plugin_config->{token}; my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; - + my $fingerprint = $plugin_config->{fingerprint}; eval { - PVE::Network::SDN::api_request("GET", "$url/ipam/aggregates/", $headers); + PVE::Network::SDN::api_request("GET", "$url/ipam/aggregates/", $headers, undef, $fingerprint); }; if ($@) { die "Can't connect to netbox api: $@"; @@ -256,34 +273,40 @@ sub on_update_hook { #helpers sub get_prefix_id { - my ($url, $cidr, $headers) = @_; - - my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/prefixes/?q=$cidr", $headers); + my ($url, $cidr, $headers, $fingerprint) = @_; + my $result = PVE::Network::SDN::api_request( + "GET", "$url/ipam/prefixes/?q=$cidr", $headers, undef, $fingerprint); my $data = @{$result->{results}}[0]; my $internalid = $data->{id}; return $internalid; } sub get_iprange_id { - my ($url, $range, $headers) = @_; - - my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-ranges/?start_address=$range->{'start-address'}&end_address=$range->{'end-address'}", $headers); + my ($url, $range, $headers, $fingerprint) = @_; + my $result = PVE::Network::SDN::api_request( + "GET", + "$url/ipam/ip-ranges/?start_address=$range->{'start-address'}&end_address=$range->{'end-address'}", + $headers, + undef, + $fingerprint + ); my $data = @{$result->{results}}[0]; my $internalid = $data->{id}; return $internalid; } sub get_ip_id { - my ($url, $ip, $headers) = @_; - my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-addresses/?q=$ip", $headers); + my ($url, $ip, $headers, $fingerprint) = @_; + my $result = PVE::Network::SDN::api_request( + "GET", "$url/ipam/ip-addresses/?q=$ip", $headers, undef, $fingerprint); my $data = @{$result->{results}}[0]; my $ip_id = $data->{id}; return $ip_id; } sub is_ip_gateway { - my ($url, $ip, $headers) = @_; - my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-addresses/?q=$ip", $headers); + my ($url, $ip, $headers, $fingerprint) = @_; + my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-addresses/?q=$ip", $headers, undef, $fingerprint); my $data = @{$result->{data}}[0]; my $description = $data->{description}; my $is_gateway = 1 if $description eq 'gateway';