diff options
| author | Hannes Duerr <h.duerr@proxmox.com> | 2025-02-10 15:19:29 +0100 | 
|---|---|---|
| committer | Thomas Lamprecht <t.lamprecht@proxmox.com> | 2025-03-06 10:00:21 +0100 | 
| commit | 3903003f313efb6da79e5c508e65c94441a9affd (patch) | |
| tree | 659d2f18ce697e26bfa3781b1e73ce762521f132 /src/PVE/Network | |
| parent | bafa528fbab7baa43620d8e6b968e6342069fc01 (diff) | |
ipam: netbox integration: add fingerprint option to api requests
Signed-off-by: Hannes Duerr <h.duerr@proxmox.com>
Tested-by: Stefan Hanreich <s.hanreich@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Diffstat (limited to 'src/PVE/Network')
| -rw-r--r-- | src/PVE/Network/SDN/Ipams/NetboxPlugin.pm | 87 | 
1 files changed, 55 insertions, 32 deletions
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';  | 
