]> git.puffer.fish Git - mirror/pve-network.git/commitdiff
ipam: add update_ip
authorAlexandre Derumier <aderumier@odiso.com>
Tue, 5 Jan 2021 09:35:24 +0000 (10:35 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Sat, 6 Feb 2021 13:50:44 +0000 (14:50 +0100)
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
PVE/Network/SDN/Ipams/PVEPlugin.pm
PVE/Network/SDN/Ipams/PhpIpamPlugin.pm
PVE/Network/SDN/Ipams/Plugin.pm
PVE/Network/SDN/Subnets.pm
PVE/Network/SDN/Vnets.pm

index 3c9921865b5177c2331b452c7a303652f1709d2e..f699daa7a667deeff982cc6a4ff6eece2f7e031e 100644 (file)
@@ -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) = @_;
 
index c02b6dba74981132a5200a1a768bd4f0601058cc..2527850109de88259609f738b0bec328d54438b8 100644 (file)
@@ -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) = @_;
 
index ab06f7b5d80970fcb351290140a5e26530c14e49..b5ff38cd372fad5106a45a348757a5bec61b777e 100644 (file)
@@ -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) = @_;
 
index 10e52126e4526b4c9f244ad4c237a9401eb28ad9..39675f2c2661dd6bb7803c2fd12ac123697a9c17 100644 (file)
@@ -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 {
index b752e2c3e08ba0d2d74a4cfbe700d10d80009807..808c1bfc309beec3ee49d8c784e5d45b4bceb48e 100644 (file)
@@ -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) = @_;
 
index d68ffab7d592ecbd01f242b58ae6492a9face104..7421adfb9e90f3d23b83b919f59e1b86fb8b38a9 100644 (file)
@@ -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;