First look ip mac.db cache if not, lookup in ipam , and cache result in mac.db
Signed-off-by: Alexandre Derumier <aderum...@odiso.com> --- src/PVE/Network/SDN/Dhcp.pm | 8 ++---- src/PVE/Network/SDN/Ipams.pm | 19 +++++++++++-- src/PVE/Network/SDN/Ipams/NetboxPlugin.pm | 25 +++++++++++++++++ src/PVE/Network/SDN/Ipams/PVEPlugin.pm | 32 ++++++++++++++++++++++ src/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm | 29 ++++++++++++++++++++ src/PVE/Network/SDN/Ipams/Plugin.pm | 6 ++++ src/PVE/Network/SDN/Vnets.pm | 11 ++++++++ 7 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/PVE/Network/SDN/Dhcp.pm b/src/PVE/Network/SDN/Dhcp.pm index 1c32fec..b3c2751 100644 --- a/src/PVE/Network/SDN/Dhcp.pm +++ b/src/PVE/Network/SDN/Dhcp.pm @@ -6,7 +6,6 @@ use warnings; use PVE::Cluster qw(cfs_read_file); use PVE::Network::SDN; -use PVE::Network::SDN::Ipams::Plugin; use PVE::Network::SDN::SubnetPlugin; use PVE::Network::SDN::Dhcp qw(config); use PVE::Network::SDN::Subnets qw(sdn_subnets_config config); @@ -21,9 +20,8 @@ PVE::Network::SDN::Dhcp::Dnsmasq->register(); PVE::Network::SDN::Dhcp::Dnsmasq->init(); sub add_mapping { - my ($vmid, $vnetid, $mac, $ip) = @_; + my ($vnetid, $mac, $ip4, $ip6) = @_; - my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1); my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid); my $zoneid = $vnet->{zone}; my $zone = PVE::Network::SDN::Zones::get_zone($zoneid); @@ -32,13 +30,13 @@ sub add_mapping { return if !$dhcptype; my $dhcp_plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($dhcptype); - $dhcp_plugin->add_ip_mapping($zoneid, $mac, $ip); + $dhcp_plugin->add_ip_mapping($zoneid, $mac, $ip4) if $ip4; + $dhcp_plugin->add_ip_mapping($zoneid, $mac, $ip6) if $ip6; } sub remove_mapping { my ($vnetid, $mac) = @_; - my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1); my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid); my $zoneid = $vnet->{zone}; my $zone = PVE::Network::SDN::Zones::get_zone($zoneid); diff --git a/src/PVE/Network/SDN/Ipams.pm b/src/PVE/Network/SDN/Ipams.pm index a459441..926df90 100644 --- a/src/PVE/Network/SDN/Ipams.pm +++ b/src/PVE/Network/SDN/Ipams.pm @@ -98,8 +98,8 @@ sub config { } sub get_plugin_config { - my ($vnet) = @_; - my $ipamid = $vnet->{ipam}; + my ($zone) = @_; + my $ipamid = $zone->{ipam}; my $ipam_cfg = PVE::Network::SDN::Ipams::config(); return $ipam_cfg->{ids}->{$ipamid}; } @@ -124,5 +124,20 @@ sub complete_sdn_vnet { return $cmdname eq 'add' ? [] : [ PVE::Network::SDN::Vnets::sdn_ipams_ids($cfg) ]; } +sub get_ips_from_mac { + my ($mac, $zoneid, $zone) = @_; + + my $macdb = read_macdb(); + return ($macdb->{macs}->{$mac}->{ip4}, $macdb->{macs}->{$mac}->{ip6}) if $macdb->{macs}->{$mac}; + + my $plugin_config = get_plugin_config($zone); + my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type}); + ($macdb->{macs}->{$mac}->{ip4}, $macdb->{macs}->{$mac}->{ip6}) = $plugin->get_ips_from_mac($plugin_config, $mac, $zoneid); + + write_macdb($macdb); + + return ($macdb->{macs}->{$mac}->{ip4}, $macdb->{macs}->{$mac}->{ip6}); +} + 1; diff --git a/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm index 2099a7f..e6cc647 100644 --- a/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm +++ b/src/PVE/Network/SDN/Ipams/NetboxPlugin.pm @@ -198,6 +198,31 @@ sub del_ip { } } +sub get_ips_from_mac { + my ($class, $plugin_config, $mac, $zoneid) = @_; + + my $url = $plugin_config->{url}; + my $token = $plugin_config->{token}; + my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"]; + + my $ip4 = undef; + my $ip6 = undef; + + my $data = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-addresses/?description__ic=$mac", $headers); + for my $ip (@{$data->{results}}) { + if ($ip->{family}->{value} == 4 && !$ip4) { + ($ip4, undef) = split(/\//, $ip->{address}); + } + + if ($ip->{family}->{value} == 6 && !$ip6) { + ($ip6, undef) = split(/\//, $ip->{address}); + } + } + + return ($ip4, $ip6); +} + + sub verify_api { my ($class, $plugin_config) = @_; diff --git a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm index 5790715..0bc2b65 100644 --- a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm +++ b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm @@ -242,6 +242,38 @@ sub del_ip { die "$@" if $@; } +sub get_ips_from_mac { + my ($class, $plugin_config, $mac, $zoneid) = @_; + + #just in case, as this should already be cached in local macs.db + + my $ip4 = undef; + my $ip6 = undef; + + my $db = read_db(); + die "zone $zoneid don't exist in ipam db" if !$db->{zones}->{$zoneid}; + my $dbzone = $db->{zones}->{$zoneid}; + my $subnets = $dbzone->{subnets}; + + for my $subnet ( keys %$subnets) { + next if Net::IP::ip_is_ipv4($subnet) && $ip4; + next if $ip6; + my $ips = $subnets->{$subnet}->{ips}; + for my $ip (keys %$ips) { + my $ipobject = $ips->{$ip}; + if ($ipobject->{mac} && $ipobject->{mac} eq $mac) { + if (Net::IP::ip_is_ipv4($ip)) { + $ip4 = $ip; + } else { + $ip6 = $ip; + } + } + } + last if $ip4 && $ip6; + } + return ($ip4, $ip6); +} + #helpers sub read_db { diff --git a/src/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/src/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm index ad5286b..1b7b666 100644 --- a/src/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm +++ b/src/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm @@ -204,6 +204,35 @@ sub del_ip { } } +sub get_ips_from_mac { + my ($class, $plugin_config, $mac, $zoneid) = @_; + + + my $url = $plugin_config->{url}; + my $token = $plugin_config->{token}; + my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token]; + + my $ip4 = undef; + my $ip6 = undef; + + my $ips = PVE::Network::SDN::api_request("GET", "$url/addresses/search_mac/$mac", $headers); + + #fixme + die "parsing of result not yet implemented"; + + for my $ip (@$ips) { +# if ($ip->{family}->{value} == 4 && !$ip4) { +# ($ip4, undef) = split(/\//, $ip->{address}); +# } +# +# if ($ip->{family}->{value} == 6 && !$ip6) { +# ($ip6, undef) = split(/\//, $ip->{address}); +# } + } + + return ($ip4, $ip6); +} + sub verify_api { my ($class, $plugin_config) = @_; diff --git a/src/PVE/Network/SDN/Ipams/Plugin.pm b/src/PVE/Network/SDN/Ipams/Plugin.pm index 4d85b81..59c7e31 100644 --- a/src/PVE/Network/SDN/Ipams/Plugin.pm +++ b/src/PVE/Network/SDN/Ipams/Plugin.pm @@ -111,6 +111,12 @@ sub del_ip { die "please implement inside plugin"; } +sub get_ips_from_mac { + my ($class, $plugin_config, $mac, $zone) = @_; + + die "please implement inside plugin"; +} + sub on_update_hook { my ($class, $plugin_config) = @_; } diff --git a/src/PVE/Network/SDN/Vnets.pm b/src/PVE/Network/SDN/Vnets.pm index 76a6caf..9ba1a1e 100644 --- a/src/PVE/Network/SDN/Vnets.pm +++ b/src/PVE/Network/SDN/Vnets.pm @@ -155,6 +155,17 @@ sub del_cidr { PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname, $skipdns); } +sub get_ips_from_mac { + my ($vnetid, $mac) = @_; + my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid); + my $zoneid = $vnet->{zone}; + my $zone = PVE::Network::SDN::Zones::get_zone($zoneid); + + my $ipam = $zone->{ipam}; + return if !$ipam; + + return PVE::Network::SDN::Ipams::get_ips_from_mac($mac, $zoneid, $zone); +} 1; -- 2.39.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel