Signed-off-by: Alexandre Derumier <aderum...@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 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel