From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 3371274FF6 for ; Fri, 4 Jun 2021 13:25:14 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id BC0E01C10B for ; Fri, 4 Jun 2021 13:25:13 +0200 (CEST) Received: from kvmformation3.odiso.net (globalOdiso.M6Lille.odiso.net [89.248.211.242]) by firstgate.proxmox.com (Proxmox) with ESMTP id 6F78A1C088 for ; Fri, 4 Jun 2021 13:25:07 +0200 (CEST) Received: by kvmformation3.odiso.net (Postfix, from userid 0) id 2504DD5429; Fri, 4 Jun 2021 13:25:01 +0200 (CEST) From: Alexandre Derumier To: pve-devel@lists.proxmox.com Date: Fri, 4 Jun 2021 13:25:00 +0200 Message-Id: <20210604112500.2349926-5-aderumier@odiso.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210604112500.2349926-1-aderumier@odiso.com> References: <20210604112500.2349926-1-aderumier@odiso.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 1 AWL -0.158 Adjusted score from AWL reputation of From: address HEADER_FROM_DIFFERENT_DOMAINS 0.249 From and EnvelopeFrom 2nd level mail domains are different KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods KHOP_HELO_FCRDNS 0.398 Relay HELO differs from its IP's reverse DNS NO_DNS_FOR_FROM 0.379 Envelope sender has no MX or A DNS records SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [phpipamplugin.pm, subnetplugin.pm, netboxplugin.pm, subnets.pm, pveplugin.pm] Subject: [pve-devel] [pve-network 4/4] subnets/ipam : fix is_gateway X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Jun 2021 11:25:14 -0000 - add lost is_gateway in subnets subnet when creating subnet - allow reuse ip as gateway in subnet create if it's already flagged gateway in the ipamdb - add tests --- PVE/Network/SDN/Ipams/NetboxPlugin.pm | 14 +++++++++++++- PVE/Network/SDN/Ipams/PVEPlugin.pm | 4 ++-- PVE/Network/SDN/Ipams/PhpIpamPlugin.pm | 18 +++++++++++++++--- PVE/Network/SDN/SubnetPlugin.pm | 2 +- PVE/Network/SDN/Subnets.pm | 4 ++-- test/ipams/netbox/expected.add_ip_notgateway | 9 +++++++++ test/ipams/phpipam/expected.add_ip_notgateway | 12 ++++++++++++ test/run_test_ipams.pl | 18 +++++++++++++++++- test/run_test_subnets.pl | 8 ++++---- 9 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 test/ipams/netbox/expected.add_ip_notgateway create mode 100644 test/ipams/phpipam/expected.add_ip_notgateway diff --git a/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/PVE/Network/SDN/Ipams/NetboxPlugin.pm index 5a03f39..f0e7168 100644 --- a/PVE/Network/SDN/Ipams/NetboxPlugin.pm +++ b/PVE/Network/SDN/Ipams/NetboxPlugin.pm @@ -93,7 +93,11 @@ sub add_ip { }; if ($@) { - die "error add subnet ip to ipam: ip already exist: $@" if !$noerr; + 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; + } } } @@ -208,6 +212,14 @@ sub get_ip_id { return $ip_id; } +sub is_ip_gateway { + my ($url, $ip, $headers) = @_; + my $result = PVE::Network::SDN::api_request("GET", "$url/addresses/search/$ip", $headers); + my $data = @{$result->{data}}[0]; + my $description = $data->{description}; + my $is_gateway = 1 if $description eq 'gateway'; + return $is_gateway; +} 1; diff --git a/PVE/Network/SDN/Ipams/PVEPlugin.pm b/PVE/Network/SDN/Ipams/PVEPlugin.pm index 8fe5bbb..3e8ffc5 100644 --- a/PVE/Network/SDN/Ipams/PVEPlugin.pm +++ b/PVE/Network/SDN/Ipams/PVEPlugin.pm @@ -95,9 +95,9 @@ sub add_ip { my $dbsubnet = $dbzone->{subnets}->{$cidr}; die "subnet '$cidr' doesn't exist in IPAM DB\n" if !$dbsubnet; - die "IP '$ip' already exist\n" if defined($dbsubnet->{ips}->{$ip}); - + die "IP '$ip' already exist\n" if (!$is_gateway && defined($dbsubnet->{ips}->{$ip})) || ($is_gateway && defined($dbsubnet->{ips}->{$ip}) && !defined($dbsubnet->{ips}->{$ip}->{gateway})); $dbsubnet->{ips}->{$ip} = {}; + $dbsubnet->{ips}->{$ip} = {gateway => 1} if $is_gateway; write_db($db); }); diff --git a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm index ed66ea9..ad5286b 100644 --- a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm +++ b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm @@ -106,10 +106,10 @@ sub add_ip { my $params = { ip => $ip, subnetId => $internalid, - is_gateway => $is_gateway, hostname => $hostname, description => $description, }; + $params->{is_gateway} = 1 if $is_gateway; $params->{mac} = $mac if $mac; eval { @@ -117,7 +117,11 @@ sub add_ip { }; if ($@) { - die "error add subnet ip to ipam: ip $ip already exist: $@" if !$noerr; + 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 $ip already exist: $@" if !$noerr; + } } } @@ -134,10 +138,10 @@ sub update_ip { die "can't find ip addresse in ipam" if !$ip_id; my $params = { - is_gateway => $is_gateway, hostname => $hostname, description => $description, }; + $params->{is_gateway} = 1 if $is_gateway; $params->{mac} = $mac if $mac; eval { @@ -242,6 +246,14 @@ sub get_ip_id { return $ip_id; } +sub is_ip_gateway { + my ($url, $ip, $headers) = @_; + my $result = PVE::Network::SDN::api_request("GET", "$url/addresses/search/$ip", $headers); + my $data = @{$result->{data}}[0]; + my $is_gateway = $data->{is_gateway}; + return $is_gateway; +} + 1; diff --git a/PVE/Network/SDN/SubnetPlugin.pm b/PVE/Network/SDN/SubnetPlugin.pm index b4c8954..15b370f 100644 --- a/PVE/Network/SDN/SubnetPlugin.pm +++ b/PVE/Network/SDN/SubnetPlugin.pm @@ -143,7 +143,7 @@ sub on_update_hook { } if(!$old_gateway || $gateway && $gateway ne $old_gateway) { my $hostname = "$vnetid-gw"; - my $description = "$vnetid gw"; + my $description = "gateway"; PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $gateway, $hostname, $mac, $description, 1); } diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm index 46d9830..0231822 100644 --- a/PVE/Network/SDN/Subnets.pm +++ b/PVE/Network/SDN/Subnets.pm @@ -232,7 +232,7 @@ sub next_free_ip { } sub add_ip { - my ($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description) = @_; + my ($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_; return if !$subnet || !$ip; @@ -259,7 +259,7 @@ sub add_ip { my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type}); eval { - $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description); + $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway); }; die $@ if $@; } diff --git a/test/ipams/netbox/expected.add_ip_notgateway b/test/ipams/netbox/expected.add_ip_notgateway new file mode 100644 index 0000000..ae876f2 --- /dev/null +++ b/test/ipams/netbox/expected.add_ip_notgateway @@ -0,0 +1,9 @@ +bless( { + '_content' => '{"address":"10.0.0.1/24","description":"mydescription mac:da:65:8f:18:9b:6f","dns_name":"myhostname"}', + '_headers' => bless( { + 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', + 'content-type' => 'application/json; charset=UTF-8' + }, 'HTTP::Headers' ), + '_method' => 'POST', + '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/')}, 'URI::http' ) + }, 'HTTP::Request' ); diff --git a/test/ipams/phpipam/expected.add_ip_notgateway b/test/ipams/phpipam/expected.add_ip_notgateway new file mode 100644 index 0000000..7a91359 --- /dev/null +++ b/test/ipams/phpipam/expected.add_ip_notgateway @@ -0,0 +1,12 @@ +bless( { + '_content' => '{"description":"mydescription","hostname":"myhostname","ip":"10.0.0.1","mac":"da:65:8f:18:9b:6f","subnetId":1}', + '_headers' => bless( { + '::std_case' => { + 'token' => 'Token' + }, + 'content-type' => 'application/json; charset=UTF-8', + 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' + }, 'HTTP::Headers' ), + '_method' => 'POST', + '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/')}, 'URI::https' ) + }, 'HTTP::Request' ); diff --git a/test/run_test_ipams.pl b/test/run_test_ipams.pl index 6743eff..27bd441 100755 --- a/test/run_test_ipams.pl +++ b/test/run_test_ipams.pl @@ -99,6 +99,9 @@ foreach my $path (@plugins) { }, get_ip_id => sub { return 1; + }, + is_ip_gateway => sub { + return 1; } ); @@ -146,9 +149,22 @@ foreach my $path (@plugins) { $test = "update_ip"; $expected = Dumper read_sdn_config("$path/expected.$test"); $name = "$ipamid $test"; - $plugin->update_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, 1); + if ($@) { + is ($@, $expected, $name); + } else { + fail($name); + } + + ## add_ip_notgateway + $is_gateway = undef; + $test = "add_ip_notgateway"; + $expected = Dumper read_sdn_config("$path/expected.$test"); + $name = "$ipamid $test"; + + $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, 1); + if ($@) { is ($@, $expected, $name); } else { diff --git a/test/run_test_subnets.pl b/test/run_test_subnets.pl index 9fca202..f6564e1 100755 --- a/test/run_test_subnets.pl +++ b/test/run_test_subnets.pl @@ -135,10 +135,10 @@ foreach my $path (@plugins) { $test = "add_ip $ip"; $name = "$testid $test"; $result = undef; - $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{}}}}}}}'; + $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{"gateway":1}}}}}}}'; eval { - PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description); + PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway); }; if ($@) { @@ -170,7 +170,7 @@ foreach my $path (@plugins) { $test = "add_second_ip $ip2"; $name = "$testid $test"; $result = undef; - $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{},"'.$ip2.'":{}}}}}}}'; + $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{"gateway":1},"'.$ip2.'":{}}}}}}}'; eval { PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip2, $hostname, $mac, $description); @@ -189,7 +189,7 @@ foreach my $path (@plugins) { $test = "find_next_freeip ($ipnextfree)"; $name = "$testid $test"; $result = undef; - $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{},"'.$ipnextfree.'":{},"'.$ip2.'":{}}}}}}}'; + $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{"gateway":1},"'.$ipnextfree.'":{},"'.$ip2.'":{}}}}}}}'; eval { $ip3 = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $description); -- 2.20.1