* [pve-devel] [PATCH pve-network 01/15] sdn: pending_config: initialize empty pending key
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 02/15] ipams: add mac address Alexandre Derumier
` (14 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN.pm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/PVE/Network/SDN.pm b/PVE/Network/SDN.pm
index 256a7c8..a20233a 100644
--- a/PVE/Network/SDN.pm
+++ b/PVE/Network/SDN.pm
@@ -104,6 +104,7 @@ sub pending_config {
$pending->{$id}->{state} = "changed";
}
}
+ $pending->{$id}->{"pending"} = {} if $pending->{$id}->{state} && !defined($pending->{$id}->{"pending"});
}
foreach my $id (sort keys %{$config_objects}) {
@@ -124,6 +125,7 @@ sub pending_config {
$pending->{$id}->{state} = "changed";
}
}
+ $pending->{$id}->{"pending"} = {} if $pending->{$id}->{state} && !defined($pending->{$id}->{"pending"});
}
return {ids => $pending};
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 02/15] ipams: add mac address
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 01/15] sdn: pending_config: initialize empty pending key Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 03/15] ipam: add update_ip Alexandre Derumier
` (13 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Ipams/NetboxPlugin.pm | 6 ++++--
PVE/Network/SDN/Ipams/PVEPlugin.pm | 4 ++--
PVE/Network/SDN/Ipams/PhpIpamPlugin.pm | 7 +++++--
PVE/Network/SDN/Ipams/Plugin.pm | 4 ++--
PVE/Network/SDN/SubnetPlugin.pm | 4 +++-
PVE/Network/SDN/Subnets.pm | 8 ++++----
PVE/Network/SDN/Vnets.pm | 8 ++++----
7 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
index 298634d..3c99218 100644
--- a/PVE/Network/SDN/Ipams/NetboxPlugin.pm
+++ b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
@@ -77,13 +77,14 @@ sub del_subnet {
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
my $mask = $subnet->{mask};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
my $section = $plugin_config->{section};
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
+ $description .= " mac:$mac" if $mac && $description;
my $params = { address => "$ip/$mask", dns_name => $hostname, description => $description };
@@ -97,7 +98,7 @@ sub add_ip {
}
sub add_next_freeip {
- my ($class, $plugin_config, $subnetid, $subnet, $hostname, $description) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
my $cidr = $subnet->{cidr};
@@ -106,6 +107,7 @@ sub add_next_freeip {
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
my $internalid = get_prefix_id($url, $cidr, $headers);
+ $description .= " mac:$mac" if $mac && $description;
my $params = { dns_name => $hostname, description => $description };
diff --git a/PVE/Network/SDN/Ipams/PVEPlugin.pm b/PVE/Network/SDN/Ipams/PVEPlugin.pm
index 4925274..c02b6db 100644
--- a/PVE/Network/SDN/Ipams/PVEPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PVEPlugin.pm
@@ -82,7 +82,7 @@ sub del_subnet {
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
my $cidr = $subnet->{cidr};
my $zone = $subnet->{zone};
@@ -106,7 +106,7 @@ sub add_ip {
}
sub add_next_freeip {
- my ($class, $plugin_config, $subnetid, $subnet, $hostname, $description) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
my $cidr = $subnet->{cidr};
my $network = $subnet->{network};
diff --git a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
index 6261764..ab06f7b 100644
--- a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
@@ -95,7 +95,7 @@ sub del_subnet {
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
@@ -111,6 +111,7 @@ sub add_ip {
hostname => $hostname,
description => $description,
};
+ $params->{mac} = $mac if $mac;
eval {
PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/addresses/", $headers, $params);
@@ -122,7 +123,7 @@ sub add_ip {
}
sub add_next_freeip {
- my ($class, $plugin_config, $subnetid, $subnet, $hostname, $description) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
my $cidr = $subnet->{cidr};
my $mask = $subnet->{mask};
@@ -137,6 +138,8 @@ sub add_next_freeip {
description => $description,
};
+ $params->{mac} = $mac if $mac;
+
my $ip = undef;
eval {
my $result = PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/addresses/first_free/$internalid/", $headers, $params);
diff --git a/PVE/Network/SDN/Ipams/Plugin.pm b/PVE/Network/SDN/Ipams/Plugin.pm
index 065225c..10e5212 100644
--- a/PVE/Network/SDN/Ipams/Plugin.pm
+++ b/PVE/Network/SDN/Ipams/Plugin.pm
@@ -75,12 +75,12 @@ sub del_subnet {
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
}
sub add_next_freeip {
- my ($class, $plugin_config, $subnetid, $subnet) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
}
sub del_ip {
diff --git a/PVE/Network/SDN/SubnetPlugin.pm b/PVE/Network/SDN/SubnetPlugin.pm
index 2d6d808..68efeb6 100644
--- a/PVE/Network/SDN/SubnetPlugin.pm
+++ b/PVE/Network/SDN/SubnetPlugin.pm
@@ -113,11 +113,13 @@ sub on_update_hook {
my $reversedns = $zone->{reversedns};
my $old_gateway = $old_subnet->{gateway} if $old_subnet;
+ my $mac = undef;
if($vnetid) {
my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
raise_param_exc({ vnet => "$vnetid don't exist"}) if !$vnet;
raise_param_exc({ vnet => "you can't add a subnet on a vlanaware vnet"}) if $vnet->{vlanaware};
+ $mac = $vnet->{mac};
}
my $pointopoint = 1 if Net::IP::ip_is_ipv4($gateway) && $mask == 32;
@@ -145,7 +147,7 @@ sub on_update_hook {
if(!$old_gateway || $gateway && $gateway ne $old_gateway) {
my $hostname = "$vnetid-gw";
my $description = "$vnetid gw";
- PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $gateway, $hostname, $description, 1);
+ PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $gateway, $hostname, $mac, $description, 1);
}
#delete old gateway after update
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index 81970a1..b752e2c 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -162,7 +162,7 @@ my $del_dns_ptr_record = sub {
};
sub next_free_ip {
- my ($zone, $subnetid, $subnet, $hostname, $description) = @_;
+ my ($zone, $subnetid, $subnet, $hostname, $mac, $description) = @_;
my $cidr = undef;
my $ip = undef;
@@ -184,7 +184,7 @@ sub next_free_ip {
my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
eval {
- $cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet, $hostname, $description);
+ $cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet, $hostname, $mac, $description);
($ip, undef) = split(/\//, $cidr);
};
die $@ if $@;
@@ -210,7 +210,7 @@ sub next_free_ip {
}
sub add_ip {
- my ($zone, $subnetid, $subnet, $ip, $hostname, $description) = @_;
+ my ($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description) = @_;
return if !$subnet || !$ip;
@@ -235,7 +235,7 @@ sub add_ip {
my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
eval {
- $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $description);
+ $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description);
};
die $@ if $@;
}
diff --git a/PVE/Network/SDN/Vnets.pm b/PVE/Network/SDN/Vnets.pm
index 1da1d57..d68ffab 100644
--- a/PVE/Network/SDN/Vnets.pm
+++ b/PVE/Network/SDN/Vnets.pm
@@ -80,7 +80,7 @@ sub get_subnets {
}
sub get_next_free_cidr {
- my ($vnetid, $hostname, $description, $ipversion) = @_;
+ my ($vnetid, $hostname, $mac, $description, $ipversion) = @_;
my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
my $zoneid = $vnet->{zone};
@@ -99,7 +99,7 @@ sub get_next_free_cidr {
$subnetcount++;
if ($zone->{ipam}) {
eval {
- $ip = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname, $description);
+ $ip = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $description);
};
warn $@ if $@;
}
@@ -111,7 +111,7 @@ sub get_next_free_cidr {
}
sub add_cidr {
- my ($vnetid, $cidr, $hostname, $description) = @_;
+ my ($vnetid, $cidr, $hostname, $mac, $description) = @_;
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
@@ -122,7 +122,7 @@ sub add_cidr {
die "ip address is not in cidr format" if !$mask;
my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
- PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $description);
+ PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
}
sub del_cidr {
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 03/15] ipam: add update_ip
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 01/15] sdn: pending_config: initialize empty pending key Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 02/15] ipams: add mac address Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 04/15] dns/ipam : move api_request helper to sdn module Alexandre Derumier
` (12 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
used to update ip address options like hostname, mac,...
don't allow to change ip address, as some ipam don't support it.
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Ipams/NetboxPlugin.pm | 23 ++++++++++++++
PVE/Network/SDN/Ipams/PVEPlugin.pm | 5 +++
PVE/Network/SDN/Ipams/PhpIpamPlugin.pm | 28 +++++++++++++++++
PVE/Network/SDN/Ipams/Plugin.pm | 17 ++++++++++
PVE/Network/SDN/Subnets.pm | 39 +++++++++++++++++++++++
PVE/Network/SDN/Vnets.pm | 43 ++++++++++++++++----------
6 files changed, 138 insertions(+), 17 deletions(-)
diff --git a/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
index 3c99218..f699daa 100644
--- a/PVE/Network/SDN/Ipams/NetboxPlugin.pm
+++ b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
@@ -97,6 +97,29 @@ sub add_ip {
}
}
+sub update_ip {
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+
+ my $mask = $subnet->{mask};
+ my $url = $plugin_config->{url};
+ my $token = $plugin_config->{token};
+ my $section = $plugin_config->{section};
+ my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
+ $description .= " mac:$mac" if $mac && $description;
+
+ my $params = { address => "$ip/$mask", dns_name => $hostname, description => $description };
+
+ my $ip_id = get_ip_id($url, $ip, $headers);
+ die "can't find ip $ip in ipam" if !$ip_id;
+
+ eval {
+ PVE::Network::SDN::Ipams::Plugin::api_request("PATCH", "$url/ipam/ip-addresses/$ip_id/", $headers, $params);
+ };
+ if ($@) {
+ die "error update ip $ip : $@";
+ }
+}
+
sub add_next_freeip {
my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
diff --git a/PVE/Network/SDN/Ipams/PVEPlugin.pm b/PVE/Network/SDN/Ipams/PVEPlugin.pm
index c02b6db..2527850 100644
--- a/PVE/Network/SDN/Ipams/PVEPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PVEPlugin.pm
@@ -105,6 +105,11 @@ sub add_ip {
die "$@" if $@;
}
+sub update_ip {
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ return;
+}
+
sub add_next_freeip {
my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
diff --git a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
index ab06f7b..b5ff38c 100644
--- a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
@@ -122,6 +122,34 @@ sub add_ip {
}
}
+sub update_ip {
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+
+ my $cidr = $subnet->{cidr};
+ my $url = $plugin_config->{url};
+ my $token = $plugin_config->{token};
+ my $section = $plugin_config->{section};
+ my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token];
+
+ my $ip_id = get_ip_id($url, $ip, $headers);
+ die "can't find ip addresse in ipam" if !$ip_id;
+
+ my $params = {
+ is_gateway => $is_gateway,
+ hostname => $hostname,
+ description => $description,
+ };
+ $params->{mac} = $mac if $mac;
+
+ eval {
+ PVE::Network::SDN::Ipams::Plugin::api_request("PATCH", "$url/addresses/$ip_id", $headers, $params);
+ };
+
+ if ($@) {
+ die "ipam: error update subnet ip $ip: $@";
+ }
+}
+
sub add_next_freeip {
my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
diff --git a/PVE/Network/SDN/Ipams/Plugin.pm b/PVE/Network/SDN/Ipams/Plugin.pm
index 10e5212..39675f2 100644
--- a/PVE/Network/SDN/Ipams/Plugin.pm
+++ b/PVE/Network/SDN/Ipams/Plugin.pm
@@ -68,23 +68,40 @@ sub parse_section_header {
sub add_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
+
+ die "please implement inside plugin";
}
sub del_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
+
+ die "please implement inside plugin";
}
sub add_ip {
my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ die "please implement inside plugin";
+}
+
+sub update_ip {
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ # only update ip attributes (mac,hostname,..). Don't change the ip addresses itself, as some ipam
+ # don't allow ip address change without del/add
+
+ die "please implement inside plugin";
}
sub add_next_freeip {
my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
+
+ die "please implement inside plugin";
}
sub del_ip {
my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
+
+ die "please implement inside plugin";
}
sub on_update_hook {
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index b752e2c..808c1bf 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -256,6 +256,45 @@ sub add_ip {
}
}
+sub update_ip {
+ my ($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description) = @_;
+
+ return if !$subnet || !$ip;
+
+ my $ipaddr = new NetAddr::IP($ip);
+ $ip = $ipaddr->canon();
+
+ my $ipamid = $zone->{ipam};
+ my $dns = $zone->{dns};
+ my $dnszone = $zone->{dnszone};
+ my $reversedns = $zone->{reversedns};
+ my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
+ my $dnszoneprefix = $subnet->{dnszoneprefix};
+
+ $hostname .= ".$dnszoneprefix" if $dnszoneprefix;
+
+ #verify dns zones before ipam
+ &$verify_dns_zone($dnszone, $dns);
+ &$verify_dns_zone($reversednszone, $reversedns);
+
+ if ($ipamid) {
+ my $ipam_cfg = PVE::Network::SDN::Ipams::config();
+ my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
+ my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
+ eval {
+ $plugin->update_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description);
+ };
+ die $@ if $@;
+ }
+
+ eval {
+ #add dns
+ &$add_dns_record($dnszone, $dns, $hostname, $ip);
+ #add reverse dns
+ &$add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
+ };
+}
+
sub del_ip {
my ($zone, $subnetid, $subnet, $ip, $hostname) = @_;
diff --git a/PVE/Network/SDN/Vnets.pm b/PVE/Network/SDN/Vnets.pm
index d68ffab..7421adf 100644
--- a/PVE/Network/SDN/Vnets.pm
+++ b/PVE/Network/SDN/Vnets.pm
@@ -79,6 +79,22 @@ sub get_subnets {
}
+sub get_subnet_from_vnet_cidr {
+ my ($vnetid, $cidr) = @_;
+
+ 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);
+
+ my ($ip, $mask) = split(/\//, $cidr);
+ die "ip address is not in cidr format" if !$mask;
+
+ my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
+
+ return ($zone, $subnetid, $subnet, $ip);
+}
+
sub get_next_free_cidr {
my ($vnetid, $hostname, $mac, $description, $ipversion) = @_;
@@ -113,31 +129,24 @@ sub get_next_free_cidr {
sub add_cidr {
my ($vnetid, $cidr, $hostname, $mac, $description) = @_;
- 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);
+ my ($zone, $subnetid, $subnet, $ip) = PVE::Network::SDN::Vnets::get_subnet_from_vnet_cidr($vnetid, $cidr);
+ PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
+}
- my ($ip, $mask) = split(/\//, $cidr);
- die "ip address is not in cidr format" if !$mask;
- my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
+sub update_cidr {
+ my ($vnetid, $cidr, $hostname, $mac, $description) = @_;
- PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
+ my ($zone, $subnetid, $subnet, $ip) = PVE::Network::SDN::Vnets::get_subnet_from_vnet_cidr($vnetid, $cidr);
+ PVE::Network::SDN::Subnets::update_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
}
sub del_cidr {
my ($vnetid, $cidr, $hostname) = @_;
- 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);
-
- my ($ip, $mask) = split(/\//, $cidr);
- die "ip address is not in cidr format" if !$mask;
- my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
-
+ my ($zone, $subnetid, $subnet, $ip) = PVE::Network::SDN::Vnets::get_subnet_from_vnet_cidr($vnetid, $cidr);
PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname);
}
+
+
1;
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 04/15] dns/ipam : move api_request helper to sdn module
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (2 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 03/15] ipam: add update_ip Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 05/15] subnets: fix del_ip rollback Alexandre Derumier
` (11 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN.pm | 47 +++++++++++++++++++++++++-
PVE/Network/SDN/Dns/Plugin.pm | 37 --------------------
PVE/Network/SDN/Dns/PowerdnsPlugin.pm | 12 +++----
PVE/Network/SDN/Ipams/NetboxPlugin.pm | 18 +++++-----
PVE/Network/SDN/Ipams/PhpIpamPlugin.pm | 18 +++++-----
PVE/Network/SDN/Ipams/Plugin.pm | 37 --------------------
6 files changed, 70 insertions(+), 99 deletions(-)
diff --git a/PVE/Network/SDN.pm b/PVE/Network/SDN.pm
index a20233a..befaaee 100644
--- a/PVE/Network/SDN.pm
+++ b/PVE/Network/SDN.pm
@@ -232,5 +232,50 @@ sub encode_value {
return $value;
}
-1;
+#helpers
+sub api_request {
+ my ($method, $url, $headers, $data) = @_;
+
+ my $encoded_data = to_json($data) if $data;
+
+ my $req = HTTP::Request->new($method,$url, $headers, $encoded_data);
+
+ my $ua = LWP::UserAgent->new(protocols_allowed => ['http', 'https'], timeout => 30);
+ my $proxy = undef;
+
+ if ($proxy) {
+ $ua->proxy(['http', 'https'], $proxy);
+ } else {
+ $ua->env_proxy;
+ }
+
+ $ua->ssl_opts(verify_hostname => 0, SSL_verify_mode => 0x00);
+
+ my $response = $ua->request($req);
+ my $code = $response->code;
+
+ if ($code !~ /^2(\d+)$/) {
+ my $msg = $response->message || 'unknown';
+ die "Invalid response from server: $code $msg\n";
+ }
+
+ my $raw = '';
+ if (defined($response->decoded_content)) {
+ $raw = $response->decoded_content;
+ } else {
+ $raw = $response->content;
+ }
+
+ return if $raw eq '';
+
+ my $json = '';
+ eval {
+ $json = from_json($raw);
+ };
+ die "api response is not a json" if $@;
+
+ return $json;
+}
+
+1;
diff --git a/PVE/Network/SDN/Dns/Plugin.pm b/PVE/Network/SDN/Dns/Plugin.pm
index be399b0..ef866b7 100644
--- a/PVE/Network/SDN/Dns/Plugin.pm
+++ b/PVE/Network/SDN/Dns/Plugin.pm
@@ -8,7 +8,6 @@ use PVE::JSONSchema;
use PVE::Cluster;
use HTTP::Request;
use LWP::UserAgent;
-use JSON;
use Data::Dumper;
use PVE::JSONSchema qw(get_standard_option);
@@ -79,40 +78,4 @@ sub on_update_hook {
my ($class, $plugin_config) = @_;
}
-#helpers
-sub api_request {
- my ($method, $url, $headers, $data) = @_;
-
- my $encoded_data = to_json($data) if $data;
-
- my $req = HTTP::Request->new($method,$url, $headers, $encoded_data);
-
- my $ua = LWP::UserAgent->new(protocols_allowed => ['http', 'https'], timeout => 30);
- my $proxy = undef;
-
- if ($proxy) {
- $ua->proxy(['http', 'https'], $proxy);
- } else {
- $ua->env_proxy;
- }
-
- $ua->ssl_opts(verify_hostname => 0, SSL_verify_mode => 0x00);
-
- my $response = $ua->request($req);
- my $code = $response->code;
-
- if ($code !~ /^2(\d+)$/) {
- my $msg = $response->message || 'unknown';
- die "Invalid response from server: $code $msg\n";
- }
-
- my $raw = '';
- if (defined($response->decoded_content)) {
- $raw = $response->decoded_content;
- } else {
- $raw = $response->content;
- }
- return from_json($raw) if $raw ne '';
-}
-
1;
diff --git a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
index 3fbd595..4c00a26 100644
--- a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
+++ b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
@@ -69,7 +69,7 @@ sub add_a_record {
my $params = { rrsets => [ $rrset ] };
eval {
- PVE::Network::SDN::Dns::Plugin::api_request("PATCH", "$url/zones/$zone", $headers, $params);
+ PVE::Network::SDN::api_request("PATCH", "$url/zones/$zone", $headers, $params);
};
if ($@) {
@@ -106,7 +106,7 @@ sub add_ptr_record {
my $params = { rrsets => [ $rrset ] };
eval {
- PVE::Network::SDN::Dns::Plugin::api_request("PATCH", "$url/zones/$zone", $headers, $params);
+ PVE::Network::SDN::api_request("PATCH", "$url/zones/$zone", $headers, $params);
};
if ($@) {
@@ -131,7 +131,7 @@ sub del_a_record {
my $params = { rrsets => [ $rrset ] };
eval {
- PVE::Network::SDN::Dns::Plugin::api_request("PATCH", "$url/zones/$zone", $headers, $params);
+ PVE::Network::SDN::api_request("PATCH", "$url/zones/$zone", $headers, $params);
};
if ($@) {
@@ -158,7 +158,7 @@ sub del_ptr_record {
my $params = { rrsets => [ $rrset ] };
eval {
- PVE::Network::SDN::Dns::Plugin::api_request("PATCH", "$url/zones/$zone", $headers, $params);
+ PVE::Network::SDN::api_request("PATCH", "$url/zones/$zone", $headers, $params);
};
if ($@) {
@@ -176,7 +176,7 @@ sub verify_zone {
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'X-API-Key' => $key];
eval {
- PVE::Network::SDN::Dns::Plugin::api_request("GET", "$url/zones/$zone", $headers);
+ PVE::Network::SDN::api_request("GET", "$url/zones/$zone", $headers);
};
if ($@) {
@@ -241,7 +241,7 @@ sub on_update_hook {
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'X-API-Key' => $key];
eval {
- PVE::Network::SDN::Dns::Plugin::api_request("GET", "$url", $headers);
+ PVE::Network::SDN::api_request("GET", "$url", $headers);
};
if ($@) {
diff --git a/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
index f699daa..eae2e59 100644
--- a/PVE/Network/SDN/Ipams/NetboxPlugin.pm
+++ b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
@@ -44,7 +44,7 @@ sub add_subnet {
my $params = { prefix => $cidr };
eval {
- my $result = PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/ipam/prefixes/", $headers, $params);
+ my $result = PVE::Network::SDN::api_request("POST", "$url/ipam/prefixes/", $headers, $params);
};
if ($@) {
die "error add subnet to ipam: $@";
@@ -68,7 +68,7 @@ sub del_subnet {
return; #fixme: check that prefix is empty exluding gateway, before delete
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers);
+ PVE::Network::SDN::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers);
};
if ($@) {
die "error deleting subnet from ipam: $@";
@@ -89,7 +89,7 @@ sub add_ip {
my $params = { address => "$ip/$mask", dns_name => $hostname, description => $description };
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/ipam/ip-addresses/", $headers, $params);
+ PVE::Network::SDN::api_request("POST", "$url/ipam/ip-addresses/", $headers, $params);
};
if ($@) {
@@ -113,7 +113,7 @@ sub update_ip {
die "can't find ip $ip in ipam" if !$ip_id;
eval {
- PVE::Network::SDN::Ipams::Plugin::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);
};
if ($@) {
die "error update ip $ip : $@";
@@ -136,7 +136,7 @@ sub add_next_freeip {
my $ip = undef;
eval {
- my $result = PVE::Network::SDN::Ipams::Plugin::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);
$ip = $result->{address};
};
@@ -160,7 +160,7 @@ sub del_ip {
die "can't find ip $ip in ipam" if !$ip_id;
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers);
+ PVE::Network::SDN::api_request("DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers);
};
if ($@) {
die "error delete ip $ip : $@";
@@ -176,7 +176,7 @@ sub verify_api {
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/ipam/aggregates/", $headers);
+ PVE::Network::SDN::api_request("GET", "$url/ipam/aggregates/", $headers);
};
if ($@) {
die "Can't connect to netbox api: $@";
@@ -194,7 +194,7 @@ sub on_update_hook {
sub get_prefix_id {
my ($url, $cidr, $headers) = @_;
- my $result = PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/ipam/prefixes/?q=$cidr", $headers);
+ my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/prefixes/?q=$cidr", $headers);
my $data = @{$result->{results}}[0];
my $internalid = $data->{id};
return $internalid;
@@ -202,7 +202,7 @@ sub get_prefix_id {
sub get_ip_id {
my ($url, $ip, $headers) = @_;
- my $result = PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/ipam/ip-addresses/?q=$ip", $headers);
+ my $result = PVE::Network::SDN::api_request("GET", "$url/ipam/ip-addresses/?q=$ip", $headers);
my $data = @{$result->{results}}[0];
my $ip_id = $data->{id};
return $ip_id;
diff --git a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
index b5ff38c..7147916 100644
--- a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
@@ -62,7 +62,7 @@ sub add_subnet {
};
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/subnets/", $headers, $params);
+ PVE::Network::SDN::api_request("POST", "$url/subnets/", $headers, $params);
};
if ($@) {
die "error add subnet to ipam: $@";
@@ -86,7 +86,7 @@ sub del_subnet {
return; #fixme: check that prefix is empty exluding gateway, before delete
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/subnets/$internalid", $headers);
+ PVE::Network::SDN::api_request("DELETE", "$url/subnets/$internalid", $headers);
};
if ($@) {
die "error deleting subnet from ipam: $@";
@@ -114,7 +114,7 @@ sub add_ip {
$params->{mac} = $mac if $mac;
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/addresses/", $headers, $params);
+ PVE::Network::SDN::api_request("POST", "$url/addresses/", $headers, $params);
};
if ($@) {
@@ -142,7 +142,7 @@ sub update_ip {
$params->{mac} = $mac if $mac;
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("PATCH", "$url/addresses/$ip_id", $headers, $params);
+ PVE::Network::SDN::api_request("PATCH", "$url/addresses/$ip_id", $headers, $params);
};
if ($@) {
@@ -170,7 +170,7 @@ sub add_next_freeip {
my $ip = undef;
eval {
- my $result = PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/addresses/first_free/$internalid/", $headers, $params);
+ my $result = PVE::Network::SDN::api_request("POST", "$url/addresses/first_free/$internalid/", $headers, $params);
$ip = $result->{data};
};
@@ -194,7 +194,7 @@ sub del_ip {
return if !$ip_id;
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/addresses/$ip_id", $headers);
+ PVE::Network::SDN::api_request("DELETE", "$url/addresses/$ip_id", $headers);
};
if ($@) {
die "error delete ip $ip: $@";
@@ -210,7 +210,7 @@ sub verify_api {
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token];
eval {
- PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/sections/$sectionid", $headers);
+ PVE::Network::SDN::api_request("GET", "$url/sections/$sectionid", $headers);
};
if ($@) {
die "Can't connect to phpipam api: $@";
@@ -229,7 +229,7 @@ sub on_update_hook {
sub get_internalid {
my ($url, $cidr, $headers) = @_;
- my $result = PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/subnets/cidr/$cidr", $headers);
+ my $result = PVE::Network::SDN::api_request("GET", "$url/subnets/cidr/$cidr", $headers);
my $data = @{$result->{data}}[0];
my $internalid = $data->{id};
return $internalid;
@@ -237,7 +237,7 @@ sub get_internalid {
sub get_ip_id {
my ($url, $ip, $headers) = @_;
- my $result = PVE::Network::SDN::Ipams::Plugin::api_request("GET", "$url/addresses/search/$ip", $headers);
+ my $result = PVE::Network::SDN::api_request("GET", "$url/addresses/search/$ip", $headers);
my $data = @{$result->{data}}[0];
my $ip_id = $data->{id};
return $ip_id;
diff --git a/PVE/Network/SDN/Ipams/Plugin.pm b/PVE/Network/SDN/Ipams/Plugin.pm
index 39675f2..a4c7dcb 100644
--- a/PVE/Network/SDN/Ipams/Plugin.pm
+++ b/PVE/Network/SDN/Ipams/Plugin.pm
@@ -108,41 +108,4 @@ sub on_update_hook {
my ($class, $plugin_config) = @_;
}
-
-#helpers
-sub api_request {
- my ($method, $url, $headers, $data) = @_;
-
- my $encoded_data = to_json($data) if $data;
-
- my $req = HTTP::Request->new($method,$url, $headers, $encoded_data);
-
- my $ua = LWP::UserAgent->new(protocols_allowed => ['http', 'https'], timeout => 30);
- my $proxy = undef;
-
- if ($proxy) {
- $ua->proxy(['http', 'https'], $proxy);
- } else {
- $ua->env_proxy;
- }
-
- $ua->ssl_opts(verify_hostname => 0, SSL_verify_mode => 0x00);
-
- my $response = $ua->request($req);
- my $code = $response->code;
-
- if ($code !~ /^2(\d+)$/) {
- my $msg = $response->message || 'unknown';
- die "Invalid response from server: $code $msg\n";
- }
-
- my $raw = '';
- if (defined($response->decoded_content)) {
- $raw = $response->decoded_content;
- } else {
- $raw = $response->content;
- }
- return from_json($raw) if $raw ne '';
-}
-
1;
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 05/15] subnets: fix del_ip rollback
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (3 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 04/15] dns/ipam : move api_request helper to sdn module Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 06/15] dns: add update record && fix powerdns Alexandre Derumier
` (10 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Subnets.pm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index 808c1bf..5446044 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -202,7 +202,7 @@ sub next_free_ip {
#rollback
my $err = $@;
eval {
- PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostname)
+ PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname)
};
die $err;
}
@@ -250,7 +250,7 @@ sub add_ip {
#rollback
my $err = $@;
eval {
- PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostname)
+ PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname)
};
die $err;
}
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 06/15] dns: add update record && fix powerdns
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (4 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 05/15] subnets: fix del_ip rollback Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 07/15] ipam: phpipam: rename get_internal to get_prefix_id (like netbox) Alexandre Derumier
` (9 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Dns/Plugin.pm | 32 +++++++++-
PVE/Network/SDN/Dns/PowerdnsPlugin.pm | 87 +++++++++++++++++++++++++--
PVE/Network/SDN/Subnets.pm | 7 ++-
PVE/Network/SDN/Vnets.pm | 4 +-
4 files changed, 119 insertions(+), 11 deletions(-)
diff --git a/PVE/Network/SDN/Dns/Plugin.pm b/PVE/Network/SDN/Dns/Plugin.pm
index ef866b7..199c170 100644
--- a/PVE/Network/SDN/Dns/Plugin.pm
+++ b/PVE/Network/SDN/Dns/Plugin.pm
@@ -67,11 +67,39 @@ sub parse_section_header {
sub add_a_record {
- my ($class, $plugin_config, $type, $zone, $reversezone, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+
+ die "please implement inside plugin";
+}
+
+sub add_ptr_record {
+ my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+
+ die "please implement inside plugin";
+}
+
+sub del_ptr_record {
+ my ($class, $plugin_config, $zone, $ip) = @_;
+
+ die "please implement inside plugin";
}
sub del_a_record {
- my ($class, $plugin_config, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+
+ die "please implement inside plugin";
+}
+
+sub verify_zone {
+ my ($class, $plugin_config, $zone) = @_;
+
+ die "please implement inside plugin";
+}
+
+sub get_reversedns_zone {
+ my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
+
+ die "please implement inside plugin";
}
sub on_update_hook {
diff --git a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
index 4c00a26..d93fb06 100644
--- a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
+++ b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
@@ -52,6 +52,19 @@ sub add_a_record {
my $type = Net::IP::ip_is_ipv6($ip) ? "AAAA" : "A";
my $fqdn = $hostname.".".$zone.".";
+ my $zonecontent = get_zone_content($plugin_config, $zone);
+ my $existing_rrset = get_zone_rrset($zonecontent, $fqdn);
+
+ my $final_records = [];
+ my $foundrecord = undef;
+ foreach my $record (@{$existing_rrset->{records}}) {
+ if($record->{content} eq $ip) {
+ $foundrecord = 1;
+ next;
+ }
+ push @$final_records, $record;
+ }
+ return if $foundrecord;
my $record = { content => $ip,
disabled => JSON::false,
@@ -59,11 +72,13 @@ sub add_a_record {
type => $type,
priority => 0 };
+ push @$final_records, $record;
+
my $rrset = { name => $fqdn,
type => $type,
ttl => $ttl,
changetype => "REPLACE",
- records => [ $record ] };
+ records => $final_records };
my $params = { rrsets => [ $rrset ] };
@@ -123,10 +138,37 @@ sub del_a_record {
my $fqdn = $hostname.".".$zone.".";
my $type = Net::IP::ip_is_ipv6($ip) ? "AAAA" : "A";
- my $rrset = { name => $fqdn,
- type => $type,
- changetype => "DELETE",
- records => [] };
+ my $zonecontent = get_zone_content($plugin_config, $zone);
+ my $existing_rrset = get_zone_rrset($zonecontent, $fqdn);
+
+ my $final_records = [];
+ my $foundrecord = undef;
+ foreach my $record (@{$existing_rrset->{records}}) {
+ if ($record->{content} eq $ip) {
+ $foundrecord = 1;
+ next;
+ }
+ push @$final_records, $record;
+ }
+ return if !$foundrecord;
+
+ my $rrset = {};
+
+ if (scalar (@{$final_records}) > 0) {
+ #if we still have other records, we rewrite them without removed ip
+ $rrset = { name => $fqdn,
+ type => $type,
+ ttl => $existing_rrset->{ttl},
+ changetype => "REPLACE",
+ records => $final_records };
+
+ } else {
+
+ $rrset = { name => $fqdn,
+ type => $type,
+ changetype => "DELETE",
+ records => [] };
+ }
my $params = { rrsets => [ $rrset ] };
@@ -176,7 +218,7 @@ sub verify_zone {
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'X-API-Key' => $key];
eval {
- PVE::Network::SDN::api_request("GET", "$url/zones/$zone", $headers);
+ PVE::Network::SDN::api_request("GET", "$url/zones/$zone?rrsets=false", $headers);
};
if ($@) {
@@ -249,6 +291,39 @@ sub on_update_hook {
}
}
+
+sub get_zone_content {
+ my ($plugin_config, $zone) = @_;
+
+ #verify that api is working
+
+ my $url = $plugin_config->{url};
+ my $key = $plugin_config->{key};
+ my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'X-API-Key' => $key];
+
+ my $result = undef;
+ eval {
+ $result = PVE::Network::SDN::api_request("GET", "$url/zones/$zone", $headers);
+ };
+
+ if ($@) {
+ die "can't read zone $zone: $@";
+ }
+ return $result;
+}
+
+sub get_zone_rrset {
+ my ($zonecontent, $name) = @_;
+
+ my $rrsetresult = undef;
+ foreach my $rrset (@{$zonecontent->{rrsets}}) {
+ next if $rrset->{name} ne $name;
+ $rrsetresult = $rrset;
+ last;
+ }
+ return $rrsetresult;
+}
+
1;
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index 5446044..25261ac 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -257,7 +257,7 @@ sub add_ip {
}
sub update_ip {
- my ($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description) = @_;
+ my ($zone, $subnetid, $subnet, $ip, $hostname, $oldhostname, $mac, $description) = @_;
return if !$subnet || !$ip;
@@ -287,10 +287,15 @@ sub update_ip {
die $@ if $@;
}
+ return if $hostname eq $oldhostname;
+
eval {
#add dns
+
+ &$del_dns_record($dnszone, $dns, $oldhostname, $ip);
&$add_dns_record($dnszone, $dns, $hostname, $ip);
#add reverse dns
+ &$del_dns_ptr_record($reversednszone, $reversedns, $ip);
&$add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
};
}
diff --git a/PVE/Network/SDN/Vnets.pm b/PVE/Network/SDN/Vnets.pm
index 7421adf..ff39eef 100644
--- a/PVE/Network/SDN/Vnets.pm
+++ b/PVE/Network/SDN/Vnets.pm
@@ -134,10 +134,10 @@ sub add_cidr {
}
sub update_cidr {
- my ($vnetid, $cidr, $hostname, $mac, $description) = @_;
+ my ($vnetid, $cidr, $hostname, $oldhostname, $mac, $description) = @_;
my ($zone, $subnetid, $subnet, $ip) = PVE::Network::SDN::Vnets::get_subnet_from_vnet_cidr($vnetid, $cidr);
- PVE::Network::SDN::Subnets::update_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
+ PVE::Network::SDN::Subnets::update_ip($zone, $subnetid, $subnet, $ip, $hostname, $oldhostname, $mac, $description);
}
sub del_cidr {
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 07/15] ipam: phpipam: rename get_internal to get_prefix_id (like netbox)
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (5 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 06/15] dns: add update record && fix powerdns Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 08/15] ipams: add noerr param Alexandre Derumier
` (8 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Ipams/PhpIpamPlugin.pm | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
index 7147916..235d553 100644
--- a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
@@ -51,7 +51,7 @@ sub add_subnet {
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token];
#search subnet
- my $internalid = get_internalid($url, $cidr, $headers);
+ my $internalid = get_prefix_id($url, $cidr, $headers);
#create subnet
if (!$internalid) {
@@ -80,7 +80,7 @@ sub del_subnet {
my $section = $plugin_config->{section};
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token];
- my $internalid = get_internalid($url, $cidr, $headers);
+ my $internalid = get_prefix_id($url, $cidr, $headers);
return if !$internalid;
return; #fixme: check that prefix is empty exluding gateway, before delete
@@ -103,7 +103,7 @@ sub add_ip {
my $section = $plugin_config->{section};
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token];
- my $internalid = get_internalid($url, $cidr, $headers);
+ my $internalid = get_prefix_id($url, $cidr, $headers);
my $params = { ip => $ip,
subnetId => $internalid,
@@ -160,7 +160,7 @@ sub add_next_freeip {
my $section = $plugin_config->{section};
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Token' => $token];
- my $internalid = get_internalid($url, $cidr, $headers);
+ my $internalid = get_prefix_id($url, $cidr, $headers);
my $params = { hostname => $hostname,
description => $description,
@@ -226,7 +226,7 @@ sub on_update_hook {
#helpers
-sub get_internalid {
+sub get_prefix_id {
my ($url, $cidr, $headers) = @_;
my $result = PVE::Network::SDN::api_request("GET", "$url/subnets/cidr/$cidr", $headers);
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 08/15] ipams: add noerr param
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (6 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 07/15] ipam: phpipam: rename get_internal to get_prefix_id (like netbox) Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 09/15] tests: add ipams tests Alexandre Derumier
` (7 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Ipams/NetboxPlugin.pm | 24 +++++++++++------------
PVE/Network/SDN/Ipams/PhpIpamPlugin.pm | 27 +++++++++++++-------------
PVE/Network/SDN/Ipams/Plugin.pm | 12 ++++++------
3 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/PVE/Network/SDN/Ipams/NetboxPlugin.pm b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
index eae2e59..5a03f39 100644
--- a/PVE/Network/SDN/Ipams/NetboxPlugin.pm
+++ b/PVE/Network/SDN/Ipams/NetboxPlugin.pm
@@ -28,7 +28,7 @@ sub options {
# Plugin implementation
sub add_subnet {
- my ($class, $plugin_config, $subnetid, $subnet) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
my $cidr = $subnet->{cidr};
my $gateway = $subnet->{gateway};
@@ -47,14 +47,14 @@ sub add_subnet {
my $result = PVE::Network::SDN::api_request("POST", "$url/ipam/prefixes/", $headers, $params);
};
if ($@) {
- die "error add subnet to ipam: $@";
+ die "error add subnet to ipam: $@" if !$noerr;
}
}
}
sub del_subnet {
- my ($class, $plugin_config, $subnetid, $subnet) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
@@ -71,13 +71,13 @@ sub del_subnet {
PVE::Network::SDN::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers);
};
if ($@) {
- die "error deleting subnet from ipam: $@";
+ die "error deleting subnet from ipam: $@" if !$noerr;
}
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
my $mask = $subnet->{mask};
my $url = $plugin_config->{url};
@@ -93,12 +93,12 @@ sub add_ip {
};
if ($@) {
- die "error add subnet ip to ipam: ip already exist: $@";
+ die "error add subnet ip to ipam: ip already exist: $@" if !$noerr;
}
}
sub update_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
my $mask = $subnet->{mask};
my $url = $plugin_config->{url};
@@ -116,12 +116,12 @@ sub update_ip {
PVE::Network::SDN::api_request("PATCH", "$url/ipam/ip-addresses/$ip_id/", $headers, $params);
};
if ($@) {
- die "error update ip $ip : $@";
+ die "error update ip $ip : $@" if !$noerr;
}
}
sub add_next_freeip {
- my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description, $noerr) = @_;
my $cidr = $subnet->{cidr};
@@ -141,14 +141,14 @@ sub add_next_freeip {
};
if ($@) {
- die "can't find free ip in subnet $cidr: $@";
+ die "can't find free ip in subnet $cidr: $@" if !$noerr;
}
return $ip;
}
sub del_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $noerr) = @_;
return if !$ip;
@@ -163,7 +163,7 @@ sub del_ip {
PVE::Network::SDN::api_request("DELETE", "$url/ipam/ip-addresses/$ip_id/", $headers);
};
if ($@) {
- die "error delete ip $ip : $@";
+ die "error delete ip $ip : $@" if !$noerr;
}
}
diff --git a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
index 235d553..ed66ea9 100644
--- a/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
@@ -38,7 +38,7 @@ sub options {
# Plugin implementation
sub add_subnet {
- my ($class, $plugin_config, $subnetid, $subnet) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
my $cidr = $subnet->{cidr};
my $network = $subnet->{network};
@@ -55,7 +55,6 @@ sub add_subnet {
#create subnet
if (!$internalid) {
-
my $params = { subnet => $network,
mask => $mask,
sectionId => $section,
@@ -65,14 +64,14 @@ sub add_subnet {
PVE::Network::SDN::api_request("POST", "$url/subnets/", $headers, $params);
};
if ($@) {
- die "error add subnet to ipam: $@";
+ die "error add subnet to ipam: $@" if !$noerr;
}
}
}
sub del_subnet {
- my ($class, $plugin_config, $subnetid, $subnet) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
@@ -89,13 +88,13 @@ sub del_subnet {
PVE::Network::SDN::api_request("DELETE", "$url/subnets/$internalid", $headers);
};
if ($@) {
- die "error deleting subnet from ipam: $@";
+ die "error deleting subnet from ipam: $@" if !$noerr;
}
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
@@ -118,12 +117,12 @@ sub add_ip {
};
if ($@) {
- die "error add subnet ip to ipam: ip $ip already exist: $@";
+ die "error add subnet ip to ipam: ip $ip already exist: $@" if !$noerr;
}
}
sub update_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
@@ -146,12 +145,12 @@ sub update_ip {
};
if ($@) {
- die "ipam: error update subnet ip $ip: $@";
+ die "ipam: error update subnet ip $ip: $@" if !$noerr;
}
}
sub add_next_freeip {
- my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description, $noerr) = @_;
my $cidr = $subnet->{cidr};
my $mask = $subnet->{mask};
@@ -175,14 +174,14 @@ sub add_next_freeip {
};
if ($@) {
- die "can't find free ip in subnet $cidr: $@";
+ die "can't find free ip in subnet $cidr: $@" if !$noerr;
}
- return "$ip/$mask";
+ return "$ip/$mask" if $ip && $mask;
}
sub del_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $noerr) = @_;
return if !$ip;
@@ -197,7 +196,7 @@ sub del_ip {
PVE::Network::SDN::api_request("DELETE", "$url/addresses/$ip_id", $headers);
};
if ($@) {
- die "error delete ip $ip: $@";
+ die "error delete ip $ip: $@" if !$noerr;
}
}
diff --git a/PVE/Network/SDN/Ipams/Plugin.pm b/PVE/Network/SDN/Ipams/Plugin.pm
index a4c7dcb..c96eeda 100644
--- a/PVE/Network/SDN/Ipams/Plugin.pm
+++ b/PVE/Network/SDN/Ipams/Plugin.pm
@@ -67,25 +67,25 @@ sub parse_section_header {
sub add_subnet {
- my ($class, $plugin_config, $subnetid, $subnet) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
die "please implement inside plugin";
}
sub del_subnet {
- my ($class, $plugin_config, $subnetid, $subnet) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $noerr) = @_;
die "please implement inside plugin";
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
die "please implement inside plugin";
}
sub update_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, $noerr) = @_;
# only update ip attributes (mac,hostname,..). Don't change the ip addresses itself, as some ipam
# don't allow ip address change without del/add
@@ -93,13 +93,13 @@ sub update_ip {
}
sub add_next_freeip {
- my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description, $noerr) = @_;
die "please implement inside plugin";
}
sub del_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $noerr) = @_;
die "please implement inside plugin";
}
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 09/15] tests: add ipams tests
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (7 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 08/15] ipams: add noerr param Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 10/15] dns: add noerr param Alexandre Derumier
` (6 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
test/Makefile | 5 +-
test/ipams/netbox/expected.add_ip | 9 +
test/ipams/netbox/expected.add_next_freeip | 9 +
test/ipams/netbox/expected.add_subnet | 9 +
test/ipams/netbox/expected.del_ip | 9 +
test/ipams/netbox/expected.del_subnet | 9 +
test/ipams/netbox/expected.update_ip | 9 +
test/ipams/netbox/ipam_config | 18 ++
test/ipams/netbox/sdn_config | 20 +++
test/ipams/phpipam/expected.add_ip | 12 ++
test/ipams/phpipam/expected.add_next_freeip | 12 ++
test/ipams/phpipam/expected.add_subnet | 12 ++
test/ipams/phpipam/expected.del_ip | 12 ++
test/ipams/phpipam/expected.del_subnet | 12 ++
test/ipams/phpipam/expected.update_ip | 12 ++
test/ipams/phpipam/ipam_config | 18 ++
test/ipams/phpipam/sdn_config | 20 +++
test/run_test_ipams.pl | 181 ++++++++++++++++++++
18 files changed, 387 insertions(+), 1 deletion(-)
create mode 100644 test/ipams/netbox/expected.add_ip
create mode 100644 test/ipams/netbox/expected.add_next_freeip
create mode 100644 test/ipams/netbox/expected.add_subnet
create mode 100644 test/ipams/netbox/expected.del_ip
create mode 100644 test/ipams/netbox/expected.del_subnet
create mode 100644 test/ipams/netbox/expected.update_ip
create mode 100644 test/ipams/netbox/ipam_config
create mode 100644 test/ipams/netbox/sdn_config
create mode 100644 test/ipams/phpipam/expected.add_ip
create mode 100644 test/ipams/phpipam/expected.add_next_freeip
create mode 100644 test/ipams/phpipam/expected.add_subnet
create mode 100644 test/ipams/phpipam/expected.del_ip
create mode 100644 test/ipams/phpipam/expected.del_subnet
create mode 100644 test/ipams/phpipam/expected.update_ip
create mode 100644 test/ipams/phpipam/ipam_config
create mode 100644 test/ipams/phpipam/sdn_config
create mode 100755 test/run_test_ipams.pl
diff --git a/test/Makefile b/test/Makefile
index b8e5de1..6eb88a1 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,6 +1,9 @@
all: test
-test: test_zones
+test: test_zones test_ipams
test_zones: run_test_zones.pl
./run_test_zones.pl
+
+test_ipams: run_test_ipams.pl
+ ./run_test_ipams.pl
diff --git a/test/ipams/netbox/expected.add_ip b/test/ipams/netbox/expected.add_ip
new file mode 100644
index 0000000..ae876f2
--- /dev/null
+++ b/test/ipams/netbox/expected.add_ip
@@ -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/netbox/expected.add_next_freeip b/test/ipams/netbox/expected.add_next_freeip
new file mode 100644
index 0000000..7f80f4c
--- /dev/null
+++ b/test/ipams/netbox/expected.add_next_freeip
@@ -0,0 +1,9 @@
+bless( {
+ '_content' => '{"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/prefixes/1/available-ips/')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/netbox/expected.add_subnet b/test/ipams/netbox/expected.add_subnet
new file mode 100644
index 0000000..62ca823
--- /dev/null
+++ b/test/ipams/netbox/expected.add_subnet
@@ -0,0 +1,9 @@
+bless( {
+ '_content' => '{"prefix":"10.0.0.0/24"}',
+ '_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/prefixes/')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/netbox/expected.del_ip b/test/ipams/netbox/expected.del_ip
new file mode 100644
index 0000000..3c41de4
--- /dev/null
+++ b/test/ipams/netbox/expected.del_ip
@@ -0,0 +1,9 @@
+bless( {
+ '_content' => '',
+ '_headers' => bless( {
+ 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567',
+ 'content-type' => 'application/json; charset=UTF-8'
+ }, 'HTTP::Headers' ),
+ '_method' => 'DELETE',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/1/')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/netbox/expected.del_subnet b/test/ipams/netbox/expected.del_subnet
new file mode 100644
index 0000000..bdadb71
--- /dev/null
+++ b/test/ipams/netbox/expected.del_subnet
@@ -0,0 +1,9 @@
+bless( {
+ '_content' => '{"address":"192.168.0.1/24","description":null,"dns_name":"toto"}',
+ '_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/netbox/expected.update_ip b/test/ipams/netbox/expected.update_ip
new file mode 100644
index 0000000..a1202ad
--- /dev/null
+++ b/test/ipams/netbox/expected.update_ip
@@ -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' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/1/')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/netbox/ipam_config b/test/ipams/netbox/ipam_config
new file mode 100644
index 0000000..a33be30
--- /dev/null
+++ b/test/ipams/netbox/ipam_config
@@ -0,0 +1,18 @@
+{
+ 'ids' => {
+ 'phpipam' => {
+ 'url' => 'https://localhost/api/apiadmin',
+ 'type' => 'phpipam',
+ 'section' => 1,
+ 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw'
+ },
+ 'pve' => {
+ 'type' => 'pve'
+ },
+ 'netbox' => {
+ 'token' => '0123456789abcdef0123456789abcdef01234567',
+ 'type' => 'netbox',
+ 'url' => 'http://localhost:8000/api'
+ }
+ },
+}
diff --git a/test/ipams/netbox/sdn_config b/test/ipams/netbox/sdn_config
new file mode 100644
index 0000000..c31847b
--- /dev/null
+++ b/test/ipams/netbox/sdn_config
@@ -0,0 +1,20 @@
+{
+ version => 1,
+ vnets => {
+ ids => {
+ myvnet => { type => "vnet", zone => "myzone" },
+ },
+ },
+
+ zones => {
+ ids => { myzone => { ipam => "netbox" } },
+ },
+
+ subnets => {
+ ids => { 'myzone-10.0.0.0-24' => {
+ 'type' => 'subnet',
+ 'vnet' => 'myvnet',
+ }
+ }
+ }
+}
diff --git a/test/ipams/phpipam/expected.add_ip b/test/ipams/phpipam/expected.add_ip
new file mode 100644
index 0000000..50af460
--- /dev/null
+++ b/test/ipams/phpipam/expected.add_ip
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"description":"mydescription","hostname":"myhostname","ip":"10.0.0.1","is_gateway":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/ipams/phpipam/expected.add_next_freeip b/test/ipams/phpipam/expected.add_next_freeip
new file mode 100644
index 0000000..d72f94f
--- /dev/null
+++ b/test/ipams/phpipam/expected.add_next_freeip
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"description":"mydescription","hostname":"myhostname","mac":"da:65:8f:18:9b:6f"}',
+ '_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/first_free/1/')}, 'URI::https' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/phpipam/expected.add_subnet b/test/ipams/phpipam/expected.add_subnet
new file mode 100644
index 0000000..b10cc5a
--- /dev/null
+++ b/test/ipams/phpipam/expected.add_subnet
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"mask":"24","sectionId":1,"subnet":"10.0.0.0"}',
+ '_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/subnets/')}, 'URI::https' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/phpipam/expected.del_ip b/test/ipams/phpipam/expected.del_ip
new file mode 100644
index 0000000..72e83cb
--- /dev/null
+++ b/test/ipams/phpipam/expected.del_ip
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'token' => 'Token'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw'
+ }, 'HTTP::Headers' ),
+ '_method' => 'DELETE',
+ '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/1')}, 'URI::https' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/phpipam/expected.del_subnet b/test/ipams/phpipam/expected.del_subnet
new file mode 100644
index 0000000..349a34f
--- /dev/null
+++ b/test/ipams/phpipam/expected.del_subnet
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"description":null,"hostname":"toto","ip":"192.168.0.1","is_gateway":null,"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/ipams/phpipam/expected.update_ip b/test/ipams/phpipam/expected.update_ip
new file mode 100644
index 0000000..96c219b
--- /dev/null
+++ b/test/ipams/phpipam/expected.update_ip
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"description":"mydescription","hostname":"myhostname","is_gateway":1,"mac":"da:65:8f:18:9b:6f"}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'token' => 'Token'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/1')}, 'URI::https' )
+ }, 'HTTP::Request' );
diff --git a/test/ipams/phpipam/ipam_config b/test/ipams/phpipam/ipam_config
new file mode 100644
index 0000000..a33be30
--- /dev/null
+++ b/test/ipams/phpipam/ipam_config
@@ -0,0 +1,18 @@
+{
+ 'ids' => {
+ 'phpipam' => {
+ 'url' => 'https://localhost/api/apiadmin',
+ 'type' => 'phpipam',
+ 'section' => 1,
+ 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw'
+ },
+ 'pve' => {
+ 'type' => 'pve'
+ },
+ 'netbox' => {
+ 'token' => '0123456789abcdef0123456789abcdef01234567',
+ 'type' => 'netbox',
+ 'url' => 'http://localhost:8000/api'
+ }
+ },
+}
diff --git a/test/ipams/phpipam/sdn_config b/test/ipams/phpipam/sdn_config
new file mode 100644
index 0000000..c774807
--- /dev/null
+++ b/test/ipams/phpipam/sdn_config
@@ -0,0 +1,20 @@
+{
+ version => 1,
+ vnets => {
+ ids => {
+ myvnet => { type => "vnet", zone => "myzone" },
+ },
+ },
+
+ zones => {
+ ids => { myzone => { ipam => "phpipam" } },
+ },
+
+ subnets => {
+ ids => { 'myzone-10.0.0.0-24' => {
+ 'type' => 'subnet',
+ 'vnet' => 'myvnet',
+ }
+ }
+ }
+}
diff --git a/test/run_test_ipams.pl b/test/run_test_ipams.pl
new file mode 100755
index 0000000..6743eff
--- /dev/null
+++ b/test/run_test_ipams.pl
@@ -0,0 +1,181 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib qw(..);
+use File::Slurp;
+
+use Test::More;
+use Test::MockModule;
+
+use PVE::Network::SDN;
+use PVE::Network::SDN::Zones;
+use PVE::Network::SDN::Controllers;
+use PVE::INotify;
+use JSON;
+
+use Data::Dumper qw(Dumper);
+$Data::Dumper::Sortkeys = 1;
+
+sub read_sdn_config {
+ my ($file) = @_;
+ # Read structure back in again
+ open my $in, '<', $file or die $!;
+ my $sdn_config;
+ {
+ local $/; # slurp mode
+ $sdn_config = eval <$in>;
+ }
+ close $in;
+
+ return $sdn_config;
+}
+
+
+#my @plugins = <./ipams/*>;
+my @plugins = read_dir( './ipams/', prefix => 1 ) ;
+
+foreach my $path (@plugins) {
+
+ my (undef, $ipamid) = split(/\//, $path);
+ my $sdn_config = read_sdn_config ("$path/sdn_config");
+
+
+ my $pve_sdn_subnets;
+ $pve_sdn_subnets = Test::MockModule->new('PVE::Network::SDN::Subnets');
+ $pve_sdn_subnets->mock(
+ config => sub {
+ return $sdn_config->{subnets};
+ },
+ );
+
+ my $pve_sdn_ipam;
+ $pve_sdn_subnets = Test::MockModule->new('PVE::Network::SDN::Ipams');
+ $pve_sdn_subnets->mock(
+ config => sub {
+ my $ipam_config = read_sdn_config ("$path/ipam_config");
+ return $ipam_config;
+ },
+ );
+
+ my $sdn_module = Test::MockModule->new("PVE::Network::SDN");
+ $sdn_module->mock(
+ config => sub {
+ return $sdn_config;
+ },
+ api_request => sub {
+ my ($method, $url, $headers, $data) = @_;
+
+ my $js = JSON->new;
+ $js->canonical(1);
+
+ my $encoded_data = $js->encode($data) if $data;
+ my $req = HTTP::Request->new($method,$url, $headers, $encoded_data);
+ die Dumper($req);
+ }
+ );
+
+
+
+ #test params;
+ my $subnetid = "myzone-10.0.0.0-24";
+ my $ip = "10.0.0.1";
+ my $hostname = "myhostname";
+ my $mac = "da:65:8f:18:9b:6f";
+ my $description = "mydescription";
+ my $is_gateway = 1;
+
+
+ my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($sdn_config->{subnets}, $subnetid, 1);
+
+ my $ipam_cfg = PVE::Network::SDN::Ipams::config();
+ my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
+ my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
+ my $sdn_ipam_plugin = Test::MockModule->new($plugin);
+ $sdn_ipam_plugin->mock(
+ get_prefix_id => sub {
+ return 1;
+ },
+ get_ip_id => sub {
+ return 1;
+ }
+ );
+
+ ## add_ip
+ my $test = "add_ip";
+ my $expected = Dumper read_sdn_config("$path/expected.$test");
+ my $name = "$ipamid $test";
+
+ $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip, $hostname, $mac, $description, $is_gateway, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+ ## add_next_freeip
+ $test = "add_next_freeip";
+ $expected = Dumper read_sdn_config("$path/expected.$test");
+ $name = "$ipamid $test";
+
+ $plugin->add_next_freeip($plugin_config, $subnetid, $subnet, $hostname, $mac, $description, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+
+ ## del_ip
+ $test = "del_ip";
+ $expected = Dumper read_sdn_config("$path/expected.$test");
+ $name = "$ipamid $test";
+
+ $plugin->del_ip($plugin_config, $subnetid, $subnet, $ip, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+ ## update_ip
+ $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);
+ }
+
+ $sdn_ipam_plugin->mock(
+ get_prefix_id => sub {
+ return undef;
+ },
+ );
+
+ ## add_subnet
+ $test = "add_subnet";
+ $expected = Dumper read_sdn_config("$path/expected.$test");
+ $name = "$ipamid $test";
+
+ $plugin->add_subnet($plugin_config, $subnetid, $subnet, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+}
+
+done_testing();
+
+
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 10/15] dns: add noerr param
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (8 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 09/15] tests: add ipams tests Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 11/15] tests: add dns tests Alexandre Derumier
` (5 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Dns/Plugin.pm | 10 +++++-----
PVE/Network/SDN/Dns/PowerdnsPlugin.pm | 22 +++++++++++-----------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/PVE/Network/SDN/Dns/Plugin.pm b/PVE/Network/SDN/Dns/Plugin.pm
index 199c170..07d0be1 100644
--- a/PVE/Network/SDN/Dns/Plugin.pm
+++ b/PVE/Network/SDN/Dns/Plugin.pm
@@ -67,31 +67,31 @@ sub parse_section_header {
sub add_a_record {
- my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_;
die "please implement inside plugin";
}
sub add_ptr_record {
- my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_;
die "please implement inside plugin";
}
sub del_ptr_record {
- my ($class, $plugin_config, $zone, $ip) = @_;
+ my ($class, $plugin_config, $zone, $ip, $noerr) = @_;
die "please implement inside plugin";
}
sub del_a_record {
- my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_;
die "please implement inside plugin";
}
sub verify_zone {
- my ($class, $plugin_config, $zone) = @_;
+ my ($class, $plugin_config, $zone, $noerr) = @_;
die "please implement inside plugin";
}
diff --git a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
index d93fb06..339ac28 100644
--- a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
+++ b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
@@ -42,7 +42,7 @@ sub options {
# Plugin implementation
sub add_a_record {
- my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_;
my $url = $plugin_config->{url};
my $key = $plugin_config->{key};
@@ -88,12 +88,12 @@ sub add_a_record {
};
if ($@) {
- die "error add $fqdn to zone $zone: $@";
+ die "error add $fqdn to zone $zone: $@" if !$noerr;
}
}
sub add_ptr_record {
- my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_;
my $url = $plugin_config->{url};
my $key = $plugin_config->{key};
@@ -125,12 +125,12 @@ sub add_ptr_record {
};
if ($@) {
- die "error add $reverseip to zone $zone: $@";
+ die "error add $reverseip to zone $zone: $@" if !$noerr;
}
}
sub del_a_record {
- my ($class, $plugin_config, $zone, $hostname, $ip) = @_;
+ my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_;
my $url = $plugin_config->{url};
my $key = $plugin_config->{key};
@@ -151,7 +151,7 @@ sub del_a_record {
push @$final_records, $record;
}
return if !$foundrecord;
-
+
my $rrset = {};
if (scalar (@{$final_records}) > 0) {
@@ -177,12 +177,12 @@ sub del_a_record {
};
if ($@) {
- die "error delete $fqdn from zone $zone: $@";
+ die "error delete $fqdn from zone $zone: $@" if !$noerr;
}
}
sub del_ptr_record {
- my ($class, $plugin_config, $zone, $ip) = @_;
+ my ($class, $plugin_config, $zone, $ip, $noerr) = @_;
my $url = $plugin_config->{url};
my $key = $plugin_config->{key};
@@ -204,12 +204,12 @@ sub del_ptr_record {
};
if ($@) {
- die "error delete $reverseip from zone $zone: $@";
+ die "error delete $reverseip from zone $zone: $@" if !$noerr;
}
}
sub verify_zone {
- my ($class, $plugin_config, $zone) = @_;
+ my ($class, $plugin_config, $zone, $noerr) = @_;
#verify that api is working
@@ -222,7 +222,7 @@ sub verify_zone {
};
if ($@) {
- die "can't read zone $zone: $@";
+ die "can't read zone $zone: $@" if !$noerr;
}
}
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 11/15] tests: add dns tests
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (9 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 10/15] dns: add noerr param Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 12/15] subnets: convert dns private function to public sub Alexandre Derumier
` (4 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
test/Makefile | 5 +-
test/dns/powerdns/dns_config | 10 +
.../expected.add_a_multiple_record.ipv4 | 13 +
.../expected.add_a_multiple_record.ipv6 | 13 +
test/dns/powerdns/expected.add_a_record.ipv4 | 12 +
test/dns/powerdns/expected.add_a_record.ipv6 | 13 +
.../dns/powerdns/expected.add_ptr_record.ipv4 | 13 +
.../dns/powerdns/expected.add_ptr_record.ipv6 | 12 +
.../expected.del_a_multiple_record.ipv4 | 13 +
.../expected.del_a_multiple_record.ipv6 | 12 +
test/dns/powerdns/expected.del_a_record.ipv4 | 13 +
test/dns/powerdns/expected.del_a_record.ipv6 | 12 +
.../dns/powerdns/expected.del_ptr_record.ipv4 | 12 +
.../dns/powerdns/expected.del_ptr_record.ipv6 | 13 +
test/dns/powerdns/expected.verify_zone | 12 +
test/dns/powerdns/sdn_config | 20 ++
test/run_test_dns.pl | 271 ++++++++++++++++++
17 files changed, 468 insertions(+), 1 deletion(-)
create mode 100644 test/dns/powerdns/dns_config
create mode 100644 test/dns/powerdns/expected.add_a_multiple_record.ipv4
create mode 100644 test/dns/powerdns/expected.add_a_multiple_record.ipv6
create mode 100644 test/dns/powerdns/expected.add_a_record.ipv4
create mode 100644 test/dns/powerdns/expected.add_a_record.ipv6
create mode 100644 test/dns/powerdns/expected.add_ptr_record.ipv4
create mode 100644 test/dns/powerdns/expected.add_ptr_record.ipv6
create mode 100644 test/dns/powerdns/expected.del_a_multiple_record.ipv4
create mode 100644 test/dns/powerdns/expected.del_a_multiple_record.ipv6
create mode 100644 test/dns/powerdns/expected.del_a_record.ipv4
create mode 100644 test/dns/powerdns/expected.del_a_record.ipv6
create mode 100644 test/dns/powerdns/expected.del_ptr_record.ipv4
create mode 100644 test/dns/powerdns/expected.del_ptr_record.ipv6
create mode 100644 test/dns/powerdns/expected.verify_zone
create mode 100644 test/dns/powerdns/sdn_config
create mode 100755 test/run_test_dns.pl
diff --git a/test/Makefile b/test/Makefile
index 6eb88a1..ca05cf7 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,9 +1,12 @@
all: test
-test: test_zones test_ipams
+test: test_zones test_ipams test_dns
test_zones: run_test_zones.pl
./run_test_zones.pl
test_ipams: run_test_ipams.pl
./run_test_ipams.pl
+
+test_dns: run_test_dns.pl
+ ./run_test_dns.pl
diff --git a/test/dns/powerdns/dns_config b/test/dns/powerdns/dns_config
new file mode 100644
index 0000000..6052366
--- /dev/null
+++ b/test/dns/powerdns/dns_config
@@ -0,0 +1,10 @@
+{
+ 'ids' => {
+ 'powerdns' => {
+ 'url' => 'http://localhost:8881/api/v1/servers/localhost',
+ 'type' => 'powerdns',
+ 'key' => '1234',
+ 'ttl' => '3600'
+ },
+ },
+}
diff --git a/test/dns/powerdns/expected.add_a_multiple_record.ipv4 b/test/dns/powerdns/expected.add_a_multiple_record.ipv4
new file mode 100644
index 0000000..0e5539f
--- /dev/null
+++ b/test/dns/powerdns/expected.add_a_multiple_record.ipv4
@@ -0,0 +1,13 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"127.0.0.1","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"A"},{"content":"10.0.0.1","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"A"}],"ttl":"3600","type":"A"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
+
diff --git a/test/dns/powerdns/expected.add_a_multiple_record.ipv6 b/test/dns/powerdns/expected.add_a_multiple_record.ipv6
new file mode 100644
index 0000000..e432e7b
--- /dev/null
+++ b/test/dns/powerdns/expected.add_a_multiple_record.ipv6
@@ -0,0 +1,13 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"2001:4860:4860::8844","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"AAAA"},{"content":"2001:4860:4860::8888","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"AAAA"}],"ttl":"3600","type":"AAAA"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
+
diff --git a/test/dns/powerdns/expected.add_a_record.ipv4 b/test/dns/powerdns/expected.add_a_record.ipv4
new file mode 100644
index 0000000..888d67f
--- /dev/null
+++ b/test/dns/powerdns/expected.add_a_record.ipv4
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"10.0.0.1","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"A"}],"ttl":"3600","type":"A"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
\ No newline at end of file
diff --git a/test/dns/powerdns/expected.add_a_record.ipv6 b/test/dns/powerdns/expected.add_a_record.ipv6
new file mode 100644
index 0000000..bfeeab7
--- /dev/null
+++ b/test/dns/powerdns/expected.add_a_record.ipv6
@@ -0,0 +1,13 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"2001:4860:4860::8888","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"AAAA"}],"ttl":"3600","type":"AAAA"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
+
diff --git a/test/dns/powerdns/expected.add_ptr_record.ipv4 b/test/dns/powerdns/expected.add_ptr_record.ipv4
new file mode 100644
index 0000000..6923971
--- /dev/null
+++ b/test/dns/powerdns/expected.add_ptr_record.ipv4
@@ -0,0 +1,13 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"1.0.0.10.in-addr.arpa.","records":[{"content":"myhostname.","disabled":false,"name":"1.0.0.10.in-addr.arpa.","priority":0,"type":"PTR"}],"ttl":"3600","type":"PTR"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
+
diff --git a/test/dns/powerdns/expected.add_ptr_record.ipv6 b/test/dns/powerdns/expected.add_ptr_record.ipv6
new file mode 100644
index 0000000..1d8049f
--- /dev/null
+++ b/test/dns/powerdns/expected.add_ptr_record.ipv6
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa.","records":[{"content":"myhostname.","disabled":false,"name":"8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa.","priority":0,"type":"PTR"}],"ttl":"3600","type":"PTR"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/dns/powerdns/expected.del_a_multiple_record.ipv4 b/test/dns/powerdns/expected.del_a_multiple_record.ipv4
new file mode 100644
index 0000000..45d76c6
--- /dev/null
+++ b/test/dns/powerdns/expected.del_a_multiple_record.ipv4
@@ -0,0 +1,13 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"127.0.0.1","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"A"}],"ttl":"3600","type":"A"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
+
diff --git a/test/dns/powerdns/expected.del_a_multiple_record.ipv6 b/test/dns/powerdns/expected.del_a_multiple_record.ipv6
new file mode 100644
index 0000000..9b56abd
--- /dev/null
+++ b/test/dns/powerdns/expected.del_a_multiple_record.ipv6
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"2001:4860:4860::8844","disabled":false,"name":"myhostname.domain.com.","priority":0,"type":"AAAA"}],"ttl":"3600","type":"AAAA"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/dns/powerdns/expected.del_a_record.ipv4 b/test/dns/powerdns/expected.del_a_record.ipv4
new file mode 100644
index 0000000..7c0cf45
--- /dev/null
+++ b/test/dns/powerdns/expected.del_a_record.ipv4
@@ -0,0 +1,13 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"DELETE","name":"myhostname.domain.com.","records":[],"type":"A"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
+
diff --git a/test/dns/powerdns/expected.del_a_record.ipv6 b/test/dns/powerdns/expected.del_a_record.ipv6
new file mode 100644
index 0000000..9494c83
--- /dev/null
+++ b/test/dns/powerdns/expected.del_a_record.ipv6
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"DELETE","name":"myhostname.domain.com.","records":[],"type":"AAAA"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/dns/powerdns/expected.del_ptr_record.ipv4 b/test/dns/powerdns/expected.del_ptr_record.ipv4
new file mode 100644
index 0000000..120485b
--- /dev/null
+++ b/test/dns/powerdns/expected.del_ptr_record.ipv4
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"DELETE","name":"1.0.0.10.in-addr.arpa.","records":[],"type":"PTR"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/dns/powerdns/expected.del_ptr_record.ipv6 b/test/dns/powerdns/expected.del_ptr_record.ipv6
new file mode 100644
index 0000000..7948e78
--- /dev/null
+++ b/test/dns/powerdns/expected.del_ptr_record.ipv6
@@ -0,0 +1,13 @@
+bless( {
+ '_content' => '{"rrsets":[{"changetype":"DELETE","name":"8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa.","records":[],"type":"PTR"}]}',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'PATCH',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' )
+ }, 'HTTP::Request' );
+
diff --git a/test/dns/powerdns/expected.verify_zone b/test/dns/powerdns/expected.verify_zone
new file mode 100644
index 0000000..b476875
--- /dev/null
+++ b/test/dns/powerdns/expected.verify_zone
@@ -0,0 +1,12 @@
+bless( {
+ '_content' => '',
+ '_headers' => bless( {
+ '::std_case' => {
+ 'x-api-key' => 'X-API-Key'
+ },
+ 'content-type' => 'application/json; charset=UTF-8',
+ 'x-api-key' => '1234'
+ }, 'HTTP::Headers' ),
+ '_method' => 'GET',
+ '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com?rrsets=false')}, 'URI::http' )
+ }, 'HTTP::Request' );
diff --git a/test/dns/powerdns/sdn_config b/test/dns/powerdns/sdn_config
new file mode 100644
index 0000000..2087729
--- /dev/null
+++ b/test/dns/powerdns/sdn_config
@@ -0,0 +1,20 @@
+{
+ version => 1,
+ vnets => {
+ ids => {
+ myvnet => { type => "vnet", zone => "myzone" },
+ },
+ },
+
+ zones => {
+ ids => { myzone => { ipam => "pve", type =>"simple", dns => "powerdns", reversedns => "powerdns", dnszone => "domain.com" } },
+ },
+
+ subnets => {
+ ids => { 'myzone-10.0.0.0-24' => {
+ 'type' => 'subnet',
+ 'vnet' => 'myvnet',
+ }
+ }
+ }
+}
diff --git a/test/run_test_dns.pl b/test/run_test_dns.pl
new file mode 100755
index 0000000..87e011e
--- /dev/null
+++ b/test/run_test_dns.pl
@@ -0,0 +1,271 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib qw(..);
+use File::Slurp;
+use Net::IP;
+
+use Test::More;
+use Test::MockModule;
+
+use PVE::Network::SDN;
+use PVE::Network::SDN::Zones;
+use PVE::Network::SDN::Controllers;
+use JSON;
+
+use Data::Dumper qw(Dumper);
+$Data::Dumper::Sortkeys = 1;
+
+sub read_sdn_config {
+ my ($file) = @_;
+ # Read structure back in again
+ open my $in, '<', $file or die $!;
+ my $sdn_config;
+ {
+ local $/; # slurp mode
+ $sdn_config = eval <$in>;
+ }
+ close $in;
+
+ return $sdn_config;
+}
+
+
+my @plugins = read_dir( './dns/', prefix => 1 ) ;
+
+foreach my $path (@plugins) {
+
+ my (undef, $dnsid) = split(/\//, $path);
+ my $sdn_config = read_sdn_config ("$path/sdn_config");
+
+
+ my $pve_sdn_dns;
+ $pve_sdn_dns = Test::MockModule->new('PVE::Network::SDN::Dns');
+ $pve_sdn_dns->mock(
+ config => sub {
+ my $dns_config = read_sdn_config ("$path/dns_config");
+ return $dns_config;
+ },
+ );
+
+ my $sdn_module = Test::MockModule->new("PVE::Network::SDN");
+ $sdn_module->mock(
+ config => sub {
+ return $sdn_config;
+ },
+ api_request => sub {
+ my ($method, $url, $headers, $data) = @_;
+
+ my $js = JSON->new;
+ $js->canonical(1);
+
+ my $encoded_data = $js->encode($data) if $data;
+ my $req = HTTP::Request->new($method,$url, $headers, $encoded_data);
+ die Dumper($req);
+ }
+ );
+
+
+
+ my $dns_cfg = PVE::Network::SDN::Dns::config();
+ my $plugin_config = $dns_cfg->{ids}->{$dnsid};
+ my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
+
+ #test params;
+ my @ips = ("10.0.0.1", "2001:4860:4860::8888");
+ my $zone = "domain.com";
+ my $hostname = "myhostname";
+
+ foreach my $ip (@ips) {
+
+ my $ipversion = Net::IP::ip_is_ipv6($ip) ? "ipv6" : "ipv4";
+ my $type = Net::IP::ip_is_ipv6($ip) ? "AAAA" : "A";
+ my $ip2 = $type eq 'AAAA' ? '2001:4860:4860::8844' : '127.0.0.1';
+ my $fqdn = $hostname.".".$zone.".";
+
+ my $sdn_dns_plugin = Test::MockModule->new($plugin);
+ $sdn_dns_plugin->mock(
+
+ get_zone_content => sub {
+ return undef;
+ },
+ get_zone_rrset => sub {
+ return undef;
+ }
+ );
+
+ ## add_a_record
+ my $test = "add_a_record";
+ my $expected = Dumper read_sdn_config("$path/expected.$test.$ipversion");
+ my $name = "$dnsid $test";
+
+ $plugin->add_a_record($plugin_config, $zone, $hostname, $ip, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+ ## add_ptr_record
+ $test = "add_ptr_record";
+ $expected = Dumper read_sdn_config("$path/expected.$test.$ipversion");
+ $name = "$dnsid $test";
+
+ $plugin->add_ptr_record($plugin_config, $zone, $hostname, $ip, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+
+ ## del_ptr_record
+ $test = "del_ptr_record";
+ $expected = Dumper read_sdn_config("$path/expected.$test.$ipversion");
+ $name = "$dnsid $test";
+
+ $plugin->del_ptr_record($plugin_config, $zone, $ip, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+
+ ## del_a_record
+
+ $sdn_dns_plugin->mock(
+
+ get_zone_content => sub {
+ return undef;
+ },
+ get_zone_rrset => sub {
+
+ my $type = Net::IP::ip_is_ipv6($ip) ? "AAAA" : "A";
+ my $fqdn = $hostname.".".$zone.".";
+ my $record = { content => $ip,
+ disabled => JSON::false,
+ name => $fqdn,
+ type => $type,
+ priority => 0 };
+
+ my $rrset = { name => $fqdn,
+ type => $type,
+ ttl => '3600',
+ records => [ $record ] };
+ return $rrset;
+ }
+ );
+
+ $test = "del_a_record";
+ $expected = Dumper read_sdn_config("$path/expected.$test.$ipversion");
+ $name = "$dnsid $test";
+
+ $plugin->del_a_record($plugin_config, $zone, $hostname, $ip, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+ ## del_a_multiple_record
+
+ $sdn_dns_plugin->mock(
+
+ get_zone_content => sub {
+ return undef;
+ },
+ get_zone_rrset => sub {
+
+ my $record = { content => $ip,
+ disabled => JSON::false,
+ name => $fqdn,
+ type => $type,
+ priority => 0 };
+
+ my $record2 = { content => $ip2,
+ disabled => JSON::false,
+ name => $fqdn,
+ type => $type,
+ priority => 0 };
+
+ my $rrset = { name => $fqdn,
+ type => $type,
+ ttl => '3600',
+ records => [ $record, $record2 ] };
+ return $rrset;
+ }
+ );
+
+ $test = "del_a_multiple_record";
+ $expected = Dumper read_sdn_config("$path/expected.$test.$ipversion");
+ $name = "$dnsid $test";
+
+ $plugin->del_a_record($plugin_config, $zone, $hostname, $ip, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+ ## add_a_multiple_record
+
+ $sdn_dns_plugin->mock(
+
+ get_zone_content => sub {
+ return undef;
+ },
+ get_zone_rrset => sub {
+
+ my $record2 = { content => $ip2,
+ disabled => JSON::false,
+ name => $fqdn,
+ type => $type,
+ priority => 0 };
+
+ my $rrset = { name => $fqdn,
+ type => $type,
+ ttl => '3600',
+ records => [ $record2 ] };
+ return $rrset;
+ }
+ );
+
+ $test = "add_a_multiple_record";
+ $expected = Dumper read_sdn_config("$path/expected.$test.$ipversion");
+ $name = "$dnsid $test";
+
+ $plugin->add_a_record($plugin_config, $zone, $hostname, $ip, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+ }
+
+ ## verify_zone
+ my $test = "verify_zone";
+ my $expected = Dumper read_sdn_config("$path/expected.$test");
+ my $name = "$dnsid $test";
+
+ $plugin->verify_zone($plugin_config, $zone, 1);
+
+ if ($@) {
+ is ($@, $expected, $name);
+ } else {
+ fail($name);
+ }
+
+}
+
+done_testing();
+
+
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 12/15] subnets: convert dns private function to public sub
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (10 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 11/15] tests: add dns tests Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 13/15] subnets: add add_subnet/del_subnet Alexandre Derumier
` (3 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Subnets.pm | 66 +++++++++++++++++++-------------------
1 file changed, 33 insertions(+), 33 deletions(-)
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index 25261ac..ec0fb66 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -94,7 +94,7 @@ sub find_ip_subnet {
return ($subnetid, $subnet);
}
-my $verify_dns_zone = sub {
+sub verify_dns_zone {
my ($zone, $dns) = @_;
return if !$zone || !$dns;
@@ -103,9 +103,9 @@ my $verify_dns_zone = sub {
my $plugin_config = $dns_cfg->{ids}->{$dns};
my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
$plugin->verify_zone($plugin_config, $zone);
-};
+}
-my $get_reversedns_zone = sub {
+sub get_reversedns_zone {
my ($subnetid, $subnet, $dns, $ip) = @_;
return if !$subnetid || !$dns || !$ip;
@@ -114,9 +114,9 @@ my $get_reversedns_zone = sub {
my $plugin_config = $dns_cfg->{ids}->{$dns};
my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
$plugin->get_reversedns_zone($plugin_config, $subnetid, $subnet, $ip);
-};
+}
-my $add_dns_record = sub {
+sub add_dns_record {
my ($zone, $dns, $hostname, $ip) = @_;
return if !$zone || !$dns || !$hostname || !$ip;
@@ -125,9 +125,9 @@ my $add_dns_record = sub {
my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
$plugin->add_a_record($plugin_config, $zone, $hostname, $ip);
-};
+}
-my $add_dns_ptr_record = sub {
+sub add_dns_ptr_record {
my ($reversezone, $zone, $dns, $hostname, $ip) = @_;
return if !$zone || !$reversezone || !$dns || !$hostname || !$ip;
@@ -137,9 +137,9 @@ my $add_dns_ptr_record = sub {
my $plugin_config = $dns_cfg->{ids}->{$dns};
my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
$plugin->add_ptr_record($plugin_config, $reversezone, $hostname, $ip);
-};
+}
-my $del_dns_record = sub {
+sub del_dns_record {
my ($zone, $dns, $hostname, $ip) = @_;
return if !$zone || !$dns || !$hostname || !$ip;
@@ -148,9 +148,9 @@ my $del_dns_record = sub {
my $plugin_config = $dns_cfg->{ids}->{$dns};
my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
$plugin->del_a_record($plugin_config, $zone, $hostname, $ip);
-};
+}
-my $del_dns_ptr_record = sub {
+sub del_dns_ptr_record {
my ($reversezone, $dns, $ip) = @_;
return if !$reversezone || !$dns || !$ip;
@@ -159,7 +159,7 @@ my $del_dns_ptr_record = sub {
my $plugin_config = $dns_cfg->{ids}->{$dns};
my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
$plugin->del_ptr_record($plugin_config, $reversezone, $ip);
-};
+}
sub next_free_ip {
my ($zone, $subnetid, $subnet, $hostname, $mac, $description) = @_;
@@ -177,7 +177,7 @@ sub next_free_ip {
$hostname .= ".$dnszoneprefix" if $dnszoneprefix;
#verify dns zones before ipam
- &$verify_dns_zone($dnszone, $dns);
+ verify_dns_zone($dnszone, $dns);
if($ipamid) {
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
@@ -191,12 +191,12 @@ sub next_free_ip {
}
eval {
- my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
+ my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
#add dns
- &$add_dns_record($dnszone, $dns, $hostname, $ip);
+ add_dns_record($dnszone, $dns, $hostname, $ip);
#add reverse dns
- &$add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
+ add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
};
if ($@) {
#rollback
@@ -221,14 +221,14 @@ sub add_ip {
my $dns = $zone->{dns};
my $dnszone = $zone->{dnszone};
my $reversedns = $zone->{reversedns};
- my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
+ my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
my $dnszoneprefix = $subnet->{dnszoneprefix};
$hostname .= ".$dnszoneprefix" if $dnszoneprefix;
#verify dns zones before ipam
- &$verify_dns_zone($dnszone, $dns);
- &$verify_dns_zone($reversednszone, $reversedns);
+ verify_dns_zone($dnszone, $dns);
+ verify_dns_zone($reversednszone, $reversedns);
if ($ipamid) {
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
@@ -242,9 +242,9 @@ sub add_ip {
eval {
#add dns
- &$add_dns_record($dnszone, $dns, $hostname, $ip);
+ add_dns_record($dnszone, $dns, $hostname, $ip);
#add reverse dns
- &$add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
+ add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
};
if ($@) {
#rollback
@@ -268,14 +268,14 @@ sub update_ip {
my $dns = $zone->{dns};
my $dnszone = $zone->{dnszone};
my $reversedns = $zone->{reversedns};
- my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
+ my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
my $dnszoneprefix = $subnet->{dnszoneprefix};
$hostname .= ".$dnszoneprefix" if $dnszoneprefix;
#verify dns zones before ipam
- &$verify_dns_zone($dnszone, $dns);
- &$verify_dns_zone($reversednszone, $reversedns);
+ verify_dns_zone($dnszone, $dns);
+ verify_dns_zone($reversednszone, $reversedns);
if ($ipamid) {
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
@@ -292,11 +292,11 @@ sub update_ip {
eval {
#add dns
- &$del_dns_record($dnszone, $dns, $oldhostname, $ip);
- &$add_dns_record($dnszone, $dns, $hostname, $ip);
+ del_dns_record($dnszone, $dns, $oldhostname, $ip);
+ add_dns_record($dnszone, $dns, $hostname, $ip);
#add reverse dns
- &$del_dns_ptr_record($reversednszone, $reversedns, $ip);
- &$add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
+ del_dns_ptr_record($reversednszone, $reversedns, $ip);
+ add_dns_ptr_record($reversednszone, $dnszone, $reversedns, $hostname, $ip);
};
}
@@ -312,13 +312,13 @@ sub del_ip {
my $dns = $zone->{dns};
my $dnszone = $zone->{dnszone};
my $reversedns = $zone->{reversedns};
- my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
+ my $reversednszone = get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
my $dnszoneprefix = $subnet->{dnszoneprefix};
$hostname .= ".$dnszoneprefix" if $dnszoneprefix;
- &$verify_dns_zone($dnszone, $dns);
- &$verify_dns_zone($reversednszone, $reversedns);
+ verify_dns_zone($dnszone, $dns);
+ verify_dns_zone($reversednszone, $reversedns);
if ($ipamid) {
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
@@ -328,8 +328,8 @@ sub del_ip {
}
eval {
- &$del_dns_record($dnszone, $dns, $hostname, $ip);
- &$del_dns_ptr_record($reversednszone, $reversedns, $ip);
+ del_dns_record($dnszone, $dns, $hostname, $ip);
+ del_dns_ptr_record($reversednszone, $reversedns, $ip);
};
if ($@) {
warn $@;
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 13/15] subnets: add add_subnet/del_subnet
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (11 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 12/15] subnets: convert dns private function to public sub Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 14/15] tests: add subnets tests Alexandre Derumier
` (2 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/API2/Network/SDN/Subnets.pm | 19 ++++++++-----------
PVE/Network/SDN/SubnetPlugin.pm | 5 +----
PVE/Network/SDN/Subnets.pm | 20 ++++++++++++++++++++
3 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/PVE/API2/Network/SDN/Subnets.pm b/PVE/API2/Network/SDN/Subnets.pm
index 07ef2e1..f7e095f 100644
--- a/PVE/API2/Network/SDN/Subnets.pm
+++ b/PVE/API2/Network/SDN/Subnets.pm
@@ -277,21 +277,18 @@ __PACKAGE__->register_method ({
sub {
my $cfg = PVE::Network::SDN::Subnets::config();
- my $scfg = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id);
+ my $scfg = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id, 1);
- my $subnets_cfg = PVE::Network::SDN::Subnets::config();
my $vnets_cfg = PVE::Network::SDN::Vnets::config();
- PVE::Network::SDN::SubnetPlugin->on_delete_hook($id, $subnets_cfg, $vnets_cfg);
+ PVE::Network::SDN::SubnetPlugin->on_delete_hook($id, $cfg, $vnets_cfg);
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $ipam = $cfg->{ids}->{$id}->{ipam};
- if ($ipam) {
- raise_param_exc({ ipam => "$ipam not existing"}) if !$ipam_cfg->{ids}->{$ipam};
- my $plugin_config = $ipam_cfg->{ids}->{$ipam};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->del_subnet($plugin_config, $id, $scfg);
- }
+ my $zone_cfg = PVE::Network::SDN::Zones::config();
+ my $vnet = $param->{vnet};
+ my $zoneid = $vnets_cfg->{ids}->{$vnet}->{zone};
+ my $zone = $zone_cfg->{ids}->{$zoneid};
+
+ PVE::Network::SDN::Subnets::del_subnet($zone, $id, $scfg);
delete $cfg->{ids}->{$id};
diff --git a/PVE/Network/SDN/SubnetPlugin.pm b/PVE/Network/SDN/SubnetPlugin.pm
index 68efeb6..b4c8954 100644
--- a/PVE/Network/SDN/SubnetPlugin.pm
+++ b/PVE/Network/SDN/SubnetPlugin.pm
@@ -129,10 +129,7 @@ sub on_update_hook {
if ($ipam) {
- my $ipam_cfg = PVE::Network::SDN::Ipams::config();
- my $plugin_config = $ipam_cfg->{ids}->{$ipam};
- my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->add_subnet($plugin_config, $subnetid, $subnet);
+ PVE::Network::SDN::Subnets::add_subnet($zone, $subnetid, $subnet);
#don't register gateway for pointopoint
return if $pointopoint;
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index ec0fb66..34b3450 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -161,6 +161,26 @@ sub del_dns_ptr_record {
$plugin->del_ptr_record($plugin_config, $reversezone, $ip);
}
+sub add_subnet {
+ my ($zone, $subnetid, $subnet) = @_;
+
+ my $ipam = $zone->{ipam};
+ my $ipam_cfg = PVE::Network::SDN::Ipams::config();
+ my $plugin_config = $ipam_cfg->{ids}->{$ipam};
+ my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
+ $plugin->add_subnet($plugin_config, $subnetid, $subnet);
+}
+
+sub del_subnet {
+ my ($zone, $subnetid, $subnet) = @_;
+
+ my $ipam = $zone->{ipam};
+ my $ipam_cfg = PVE::Network::SDN::Ipams::config();
+ my $plugin_config = $ipam_cfg->{ids}->{$ipam};
+ my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
+ $plugin->del_subnet($plugin_config, $subnetid, $subnet);
+}
+
sub next_free_ip {
my ($zone, $subnetid, $subnet, $hostname, $mac, $description) = @_;
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 14/15] tests: add subnets tests
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (12 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 13/15] subnets: add add_subnet/del_subnet Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-02-06 13:56 ` Thomas Lamprecht
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 15/15] fix coding style NetAddr::IP->new Alexandre Derumier
2021-02-06 13:57 ` [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Thomas Lamprecht
15 siblings, 1 reply; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
test/Makefile | 5 +-
test/run_test_subnets.pl | 273 ++++++++++++++++++++++++++++++++++
test/subnets/ipv4/ipam_config | 18 +++
test/subnets/ipv4/sdn_config | 20 +++
test/subnets/ipv6/ipam_config | 18 +++
test/subnets/ipv6/sdn_config | 20 +++
6 files changed, 353 insertions(+), 1 deletion(-)
create mode 100755 test/run_test_subnets.pl
create mode 100644 test/subnets/ipv4/ipam_config
create mode 100644 test/subnets/ipv4/sdn_config
create mode 100644 test/subnets/ipv6/ipam_config
create mode 100644 test/subnets/ipv6/sdn_config
diff --git a/test/Makefile b/test/Makefile
index ca05cf7..eedc4e0 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,6 +1,6 @@
all: test
-test: test_zones test_ipams test_dns
+test: test_zones test_ipams test_dns test_subnets
test_zones: run_test_zones.pl
./run_test_zones.pl
@@ -10,3 +10,6 @@ test_ipams: run_test_ipams.pl
test_dns: run_test_dns.pl
./run_test_dns.pl
+
+test_subnets: run_test_subnets.pl
+ ./run_test_subnets.pl
diff --git a/test/run_test_subnets.pl b/test/run_test_subnets.pl
new file mode 100755
index 0000000..6241f55
--- /dev/null
+++ b/test/run_test_subnets.pl
@@ -0,0 +1,273 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib qw(..);
+use File::Slurp;
+
+use Test::More;
+use Test::MockModule;
+
+use PVE::Network::SDN;
+use PVE::Network::SDN::Zones;
+use PVE::Network::SDN::Controllers;
+use PVE::INotify;
+use JSON;
+
+use Data::Dumper qw(Dumper);
+$Data::Dumper::Sortkeys = 1;
+
+sub read_sdn_config {
+ my ($file) = @_;
+ # Read structure back in again
+ open my $in, '<', $file or die $!;
+ my $sdn_config;
+ {
+ local $/; # slurp mode
+ $sdn_config = eval <$in>;
+ }
+ close $in;
+
+ return $sdn_config;
+}
+
+
+my @plugins = read_dir( './subnets/', prefix => 1 ) ;
+
+foreach my $path (@plugins) {
+
+ my (undef, $testid) = split(/\//, $path);
+
+ my $sdn_config = read_sdn_config ("$path/sdn_config");
+
+
+ my $pve_sdn_subnets;
+ $pve_sdn_subnets = Test::MockModule->new('PVE::Network::SDN::Subnets');
+ $pve_sdn_subnets->mock(
+ config => sub {
+ return $sdn_config->{subnets};
+ },
+ verify_dns_zone => sub {
+ return;
+ },
+ add_dns_record => sub {
+ return;
+ }
+ );
+
+
+ my $js = JSON->new;
+ $js->canonical(1);
+
+
+ #test params;
+ my $subnets = $sdn_config->{subnets}->{ids};
+ my $subnetid = (keys %{$subnets})[0];
+ my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($sdn_config->{subnets}, $subnetid, 1);
+
+ my $subnet_cidr = $subnet->{cidr};
+ my $iplist = NetAddr::IP->new($subnet_cidr);
+ $iplist++;
+ my $ip = $iplist->canon();
+ $iplist++;
+ my $ipnextfree = $iplist->canon();
+ $iplist++;
+ my $ip2 = $iplist->canon();
+
+ my $ip3 = undef;
+ my $hostname = "myhostname";
+ my $mac = "da:65:8f:18:9b:6f";
+ my $description = "mydescription";
+ my $is_gateway = 1;
+ my $ipamdb = {};
+
+ my $zone = PVE::Network::SDN::Zones::get_zone("myzone");
+
+ my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup('pve');
+ my $sdn_ipam_plugin = Test::MockModule->new($plugin);
+ $sdn_ipam_plugin->mock(
+ read_db => sub {
+ return $ipamdb;
+ },
+ write_db => sub {
+ my ($cfg) = @_;
+ $ipamdb = $cfg;
+ }
+ );
+
+ ## add_subnet
+ my $test = "add_subnet";
+ my $name = "$testid $test";
+ my $result = undef;
+ my $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{}}}}}}';
+
+ eval {
+ $plugin->add_subnet(undef, $subnetid, $subnet, 1);
+ };
+
+ if ($@) {
+ fail($name);
+ } else {
+ $result = $js->encode($plugin->read_db());
+ is ($result, $expected, $name);
+ }
+
+ ## add_ip
+ $test = "add_ip";
+ $name = "$testid $test";
+ $result = undef;
+ $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{}}}}}}}';
+
+ eval {
+ PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
+ };
+
+ if ($@) {
+ fail("$name : $@");
+ } else {
+ $result = $js->encode($plugin->read_db());
+ is ($result, $expected, $name);
+ }
+
+ ## add_already_exist_ip
+ $test = "add_already_exist_ip";
+ $name = "$testid $test";
+
+ eval {
+ PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
+ };
+
+ if ($@) {
+ is (undef, undef, $name);
+ } else {
+ fail("$name : $@");
+ }
+
+ ## add_second_ip
+ $test = "add_second_ip";
+ $name = "$testid $test";
+ $result = undef;
+ $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{},"'.$ip2.'":{}}}}}}}';
+
+ eval {
+ PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip2, $hostname, $mac, $description);
+ };
+
+ if ($@) {
+ fail("$name : $@");
+ } else {
+ $result = $js->encode($plugin->read_db());
+ is ($result, $expected, $name);
+ }
+
+
+ ## add_next_free
+ $test = "add_next_freeip";
+ $name = "$testid $test";
+ $result = undef;
+ $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ip.'":{},"'.$ipnextfree.'":{},"'.$ip2.'":{}}}}}}}';
+
+ eval {
+ $ip3 = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $description);
+ };
+
+ if ($@) {
+ fail("$name : $@");
+ } else {
+ $result = $js->encode($plugin->read_db());
+ is ($result, $expected, $name);
+ }
+
+ ## del_ip
+ $test = "del_ip";
+ $name = "$testid $test";
+ $result = undef;
+ $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ipnextfree.'":{},"'.$ip2.'":{}}}}}}}';
+
+ eval {
+ PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname);
+ };
+
+ if ($@) {
+ fail("$name : $@");
+ } else {
+ $result = $js->encode($plugin->read_db());
+ is ($result, $expected, $name);
+ }
+
+ ## del_subnet_not_empty
+ $test = "del_subnet_not_empty";
+ $name = "$testid $test";
+ $result = undef;
+ $expected = undef;
+
+ eval {
+ PVE::Network::SDN::Subnets::del_subnet($zone, $subnetid, $subnet);
+ };
+
+ if ($@) {
+ is ($result, $expected, $name);
+ } else {
+ fail("$name : $@");
+ }
+
+
+
+ ## add_ip_rollback_failing_dns
+ $test = "add_ip_rollback_failing_dns";
+
+ $pve_sdn_subnets->mock(
+ config => sub {
+ return $sdn_config->{subnets};
+ },
+ verify_dns_zone => sub {
+ return;
+ },
+ add_dns_record => sub {
+ die "error add dns record";
+ return;
+ }
+ );
+
+ $name = "$testid $test";
+ $result = undef;
+ $expected = '{"zones":{"myzone":{"subnets":{"'.$subnet_cidr.'":{"ips":{"'.$ipnextfree.'":{},"'.$ip2.'":{}}}}}}}';
+
+ eval {
+ PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
+ };
+
+ if ($@) {
+ $result = $js->encode($plugin->read_db());
+ is ($result, $expected, $name);
+ } else {
+ fail("$name : $@");
+ }
+
+
+ ## del_empty_subnet
+ $test = "del_empty_subnet";
+ $name = "$testid $test";
+ $result = undef;
+ $expected = '{"zones":{"myzone":{"subnets":{}}}}';
+
+ PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip2, $hostname);
+ PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip3, $hostname);
+
+ eval {
+ PVE::Network::SDN::Subnets::del_subnet($zone, $subnetid, $subnet);
+ };
+
+ if ($@) {
+ fail("$name : $@");
+ } else {
+ $result = $js->encode($plugin->read_db());
+ is ($result, $expected, $name);
+ }
+
+}
+
+done_testing();
+
+
diff --git a/test/subnets/ipv4/ipam_config b/test/subnets/ipv4/ipam_config
new file mode 100644
index 0000000..a33be30
--- /dev/null
+++ b/test/subnets/ipv4/ipam_config
@@ -0,0 +1,18 @@
+{
+ 'ids' => {
+ 'phpipam' => {
+ 'url' => 'https://localhost/api/apiadmin',
+ 'type' => 'phpipam',
+ 'section' => 1,
+ 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw'
+ },
+ 'pve' => {
+ 'type' => 'pve'
+ },
+ 'netbox' => {
+ 'token' => '0123456789abcdef0123456789abcdef01234567',
+ 'type' => 'netbox',
+ 'url' => 'http://localhost:8000/api'
+ }
+ },
+}
diff --git a/test/subnets/ipv4/sdn_config b/test/subnets/ipv4/sdn_config
new file mode 100644
index 0000000..32c548b
--- /dev/null
+++ b/test/subnets/ipv4/sdn_config
@@ -0,0 +1,20 @@
+{
+ version => 1,
+ vnets => {
+ ids => {
+ myvnet => { type => "vnet", zone => "myzone" },
+ },
+ },
+
+ zones => {
+ ids => { myzone => { ipam => "pve", type =>"simple", dns => "powerdns", dnszone => "domain.com" } },
+ },
+
+ subnets => {
+ ids => { 'myzone-10.0.0.0-24' => {
+ 'type' => 'subnet',
+ 'vnet' => 'myvnet',
+ }
+ }
+ }
+}
diff --git a/test/subnets/ipv6/ipam_config b/test/subnets/ipv6/ipam_config
new file mode 100644
index 0000000..a33be30
--- /dev/null
+++ b/test/subnets/ipv6/ipam_config
@@ -0,0 +1,18 @@
+{
+ 'ids' => {
+ 'phpipam' => {
+ 'url' => 'https://localhost/api/apiadmin',
+ 'type' => 'phpipam',
+ 'section' => 1,
+ 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw'
+ },
+ 'pve' => {
+ 'type' => 'pve'
+ },
+ 'netbox' => {
+ 'token' => '0123456789abcdef0123456789abcdef01234567',
+ 'type' => 'netbox',
+ 'url' => 'http://localhost:8000/api'
+ }
+ },
+}
diff --git a/test/subnets/ipv6/sdn_config b/test/subnets/ipv6/sdn_config
new file mode 100644
index 0000000..2e5b824
--- /dev/null
+++ b/test/subnets/ipv6/sdn_config
@@ -0,0 +1,20 @@
+{
+ version => 1,
+ vnets => {
+ ids => {
+ myvnet => { type => "vnet", zone => "myzone" },
+ },
+ },
+
+ zones => {
+ ids => { myzone => { ipam => "pve", type =>"simple", dns => "powerdns", dnszone => "domain.com" } },
+ },
+
+ subnets => {
+ ids => { 'myzone-2a0a:1580:2000::-56' => {
+ 'type' => 'subnet',
+ 'vnet' => 'myvnet',
+ }
+ }
+ }
+}
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [pve-devel] [PATCH pve-network 14/15] tests: add subnets tests
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 14/15] tests: add subnets tests Alexandre Derumier
@ 2021-02-06 13:56 ` Thomas Lamprecht
2021-02-07 14:09 ` aderumier
0 siblings, 1 reply; 20+ messages in thread
From: Thomas Lamprecht @ 2021-02-06 13:56 UTC (permalink / raw)
To: Proxmox VE development discussion, Alexandre Derumier
I get some errors from this test, did not really investigated though.
./run_test_subnets.pl
ok 1 - ipv4 add_subnet
not ok 2 - ipv4 add_ip
# Failed test 'ipv4 add_ip'
# at ./run_test_subnets.pl line 130.
# got: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{"10.0.0.1":{}}}}}}}'
not ok 3 - ipv4 add_already_exist_ip :
# Failed test 'ipv4 add_already_exist_ip : '
# at ./run_test_subnets.pl line 144.
not ok 4 - ipv4 add_second_ip
# Failed test 'ipv4 add_second_ip'
# at ./run_test_subnets.pl line 161.
# got: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{"10.0.0.1":{},"10.0.0.3":{}}}}}}}'
not ok 5 - ipv4 add_next_freeip
# Failed test 'ipv4 add_next_freeip'
# at ./run_test_subnets.pl line 179.
# got: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{"10.0.0.1":{},"10.0.0.2":{},"10.0.0.3":{}}}}}}}'
not ok 6 - ipv4 del_ip
# Failed test 'ipv4 del_ip'
# at ./run_test_subnets.pl line 196.
# got: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{"10.0.0.2":{},"10.0.0.3":{}}}}}}}'
Use of uninitialized value $ipam in hash element at ../PVE/Network/SDN/Subnets.pm line 179.
ok 7 - ipv4 del_subnet_not_empty
not ok 8 - ipv4 add_ip_rollback_failing_dns
# Failed test 'ipv4 add_ip_rollback_failing_dns'
# at ./run_test_subnets.pl line 243.
# got: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"10.0.0.0/24":{"ips":{"10.0.0.2":{},"10.0.0.3":{}}}}}}}'
Use of uninitialized value $ipam in hash element at ../PVE/Network/SDN/Subnets.pm line 179.
not ok 9 - ipv4 del_empty_subnet : cannot lookup undefined type! at ../PVE/Network/SDN/Subnets.pm line 180.
#
# Failed test 'ipv4 del_empty_subnet : cannot lookup undefined type! at ../PVE/Network/SDN/Subnets.pm line 180.
# '
# at ./run_test_subnets.pl line 262.
ok 10 - ipv6 add_subnet
not ok 11 - ipv6 add_ip
# Failed test 'ipv6 add_ip'
# at ./run_test_subnets.pl line 130.
# got: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{"2a0a:1580:2000::1":{}}}}}}}'
not ok 12 - ipv6 add_already_exist_ip :
# Failed test 'ipv6 add_already_exist_ip : '
# at ./run_test_subnets.pl line 144.
not ok 13 - ipv6 add_second_ip
# Failed test 'ipv6 add_second_ip'
# at ./run_test_subnets.pl line 161.
# got: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{"2a0a:1580:2000::1":{},"2a0a:1580:2000::3":{}}}}}}}'
not ok 14 - ipv6 add_next_freeip
# Failed test 'ipv6 add_next_freeip'
# at ./run_test_subnets.pl line 179.
# got: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{"2a0a:1580:2000::1":{},"2a0a:1580:2000::2":{},"2a0a:1580:2000::3":{}}}}}}}'
not ok 15 - ipv6 del_ip
# Failed test 'ipv6 del_ip'
# at ./run_test_subnets.pl line 196.
# got: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{"2a0a:1580:2000::2":{},"2a0a:1580:2000::3":{}}}}}}}'
Use of uninitialized value $ipam in hash element at ../PVE/Network/SDN/Subnets.pm line 179.
ok 16 - ipv6 del_subnet_not_empty
not ok 17 - ipv6 add_ip_rollback_failing_dns
# Failed test 'ipv6 add_ip_rollback_failing_dns'
# at ./run_test_subnets.pl line 243.
# got: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{}}}}}}'
# expected: '{"zones":{"myzone":{"subnets":{"2a0a:1580:2000::/56":{"ips":{"2a0a:1580:2000::2":{},"2a0a:1580:2000::3":{}}}}}}}'
Use of uninitialized value $ipam in hash element at ../PVE/Network/SDN/Subnets.pm line 179.
not ok 18 - ipv6 del_empty_subnet : cannot lookup undefined type! at ../PVE/Network/SDN/Subnets.pm line 180.
#
# Failed test 'ipv6 del_empty_subnet : cannot lookup undefined type! at ../PVE/Network/SDN/Subnets.pm line 180.
# '
# at ./run_test_subnets.pl line 262.
1..18
# Looks like you failed 14 tests of 18.
^ permalink raw reply [flat|nested] 20+ messages in thread
* [pve-devel] [PATCH pve-network 15/15] fix coding style NetAddr::IP->new
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (13 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 14/15] tests: add subnets tests Alexandre Derumier
@ 2021-01-05 9:35 ` Alexandre Derumier
2021-02-06 13:57 ` [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Thomas Lamprecht
15 siblings, 0 replies; 20+ messages in thread
From: Alexandre Derumier @ 2021-01-05 9:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
PVE/Network/SDN/Dns/PowerdnsPlugin.pm | 2 +-
PVE/Network/SDN/Ipams/PVEPlugin.pm | 2 +-
PVE/Network/SDN/Subnets.pm | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
index 339ac28..096d131 100644
--- a/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
+++ b/PVE/Network/SDN/Dns/PowerdnsPlugin.pm
@@ -237,7 +237,7 @@ sub get_reversedns_zone {
if (Net::IP::ip_is_ipv4($ip)) {
my ($ipblock1, $ipblock2, $ipblock3, $ipblock4) = split(/\./, $ip);
- my $ipv4 = new NetAddr::IP($cidr);
+ my $ipv4 = NetAddr::IP->new($cidr);
#private addresse #powerdns built-in private zone : serve-rfc1918
if($ipv4->is_rfc1918()) {
if ($ipblock1 == 192) {
diff --git a/PVE/Network/SDN/Ipams/PVEPlugin.pm b/PVE/Network/SDN/Ipams/PVEPlugin.pm
index 2527850..7e2fb77 100644
--- a/PVE/Network/SDN/Ipams/PVEPlugin.pm
+++ b/PVE/Network/SDN/Ipams/PVEPlugin.pm
@@ -131,7 +131,7 @@ sub add_next_freeip {
die "cannot find free IP in subnet '$cidr'\n" if defined($dbsubnet->{ips}->{$network});
$freeip = $network;
} else {
- my $iplist = new NetAddr::IP($cidr);
+ my $iplist = NetAddr::IP->new($cidr);
my $broadcast = $iplist->broadcast();
while(1) {
diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm
index 34b3450..0cbf5fd 100644
--- a/PVE/Network/SDN/Subnets.pm
+++ b/PVE/Network/SDN/Subnets.pm
@@ -234,7 +234,7 @@ sub add_ip {
return if !$subnet || !$ip;
- my $ipaddr = new NetAddr::IP($ip);
+ my $ipaddr = NetAddr::IP->new($ip);
$ip = $ipaddr->canon();
my $ipamid = $zone->{ipam};
@@ -281,7 +281,7 @@ sub update_ip {
return if !$subnet || !$ip;
- my $ipaddr = new NetAddr::IP($ip);
+ my $ipaddr = NetAddr::IP->new($ip);
$ip = $ipaddr->canon();
my $ipamid = $zone->{ipam};
@@ -325,7 +325,7 @@ sub del_ip {
return if !$subnet || !$ip;
- my $ipaddr = new NetAddr::IP($ip);
+ my $ipaddr = NetAddr::IP->new($ip);
$ip = $ipaddr->canon();
my $ipamid = $zone->{ipam};
--
2.20.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests
2021-01-05 9:35 [pve-devel] [PATCH pve-network 00/15] bugfix && unit tests Alexandre Derumier
` (14 preceding siblings ...)
2021-01-05 9:35 ` [pve-devel] [PATCH pve-network 15/15] fix coding style NetAddr::IP->new Alexandre Derumier
@ 2021-02-06 13:57 ` Thomas Lamprecht
2021-02-07 14:26 ` aderumier
15 siblings, 1 reply; 20+ messages in thread
From: Thomas Lamprecht @ 2021-02-06 13:57 UTC (permalink / raw)
To: Proxmox VE development discussion, Alexandre Derumier
applied all but this one:
> tests: add subnets tests
as my build fails with it (see reply to that patch)
much much thanks for the work here!
^ permalink raw reply [flat|nested] 20+ messages in thread