all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH v2 pve-container] POC : add/del/update ip from vnet-subnet-ipam
@ 2020-08-24 16:49 Alexandre Derumier
  2020-09-07 16:40 ` Thomas Lamprecht
  0 siblings, 1 reply; 7+ messages in thread
From: Alexandre Derumier @ 2020-08-24 16:49 UTC (permalink / raw)
  To: pve-devel

This is a POC to call ip to retreive ip address from ipam.

(it's really just a poc && buggt , it need to be improve for vnet changes, pending config apply/revert,...)
---
 src/PVE/LXC/Config.pm | 107 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 106 insertions(+), 1 deletion(-)

diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index 5bf12d5..05498e2 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -11,6 +11,14 @@ use PVE::INotify;
 use PVE::JSONSchema qw(get_standard_option);
 use PVE::Tools;
 
+my $have_sdn;
+eval {
+    require PVE::Network::SDN::Vnets;
+    require PVE::Network::SDN::Subnets;
+    $have_sdn = 1;
+};
+
+
 use base qw(PVE::AbstractConfig);
 
 my $nodename = PVE::INotify::nodename();
@@ -1145,7 +1153,6 @@ sub parse_lxc_network {
 	my $dc = PVE::Cluster::cfs_read_file('datacenter.cfg');
 	$res->{hwaddr} = PVE::Tools::random_ether_addr($dc->{mac_prefix});
     }
-
     return $res;
 }
 
@@ -1225,6 +1232,8 @@ sub vmconfig_hotplug_pending {
 		$cgroup->change_cpu_shares(undef, $confdesc->{cpuunits}->{default});
 	    } elsif ($opt =~ m/^net(\d)$/) {
 		my $netid = $1;
+		my $net = $class->parse_lxc_network($conf->{$opt});
+		delete_net_ip($conf->{hostname}, $net);
 		PVE::Network::veth_delete("veth${vmid}i$netid");
 	    } else {
 		die "skip\n"; # skip non-hotpluggable opts
@@ -1251,6 +1260,7 @@ sub vmconfig_hotplug_pending {
 	    } elsif ($opt =~ m/^net(\d+)$/) {
 		my $netid = $1;
 		my $net = $class->parse_lxc_network($value);
+		update_net_ip($conf->{hostname}, $net);
 		$value = $class->print_lxc_network($net);
 		PVE::LXC::update_net($vmid, $conf, $opt, $net, $netid, $rootdir);
 	    } elsif ($opt eq 'memory' || $opt eq 'swap') {
@@ -1327,6 +1337,8 @@ sub vmconfig_apply_pending {
 	    } elsif ($opt =~ m/^net(\d+)$/) {
 		my $netid = $1;
 		my $net = $class->parse_lxc_network($conf->{pending}->{$opt});
+		my $oldnet = $class->parse_lxc_network($conf->{$opt});
+		update_net_ip($conf->{hostname}, $net, $oldnet);
 		$conf->{pending}->{$opt} = $class->print_lxc_network($net);
 	    }
 	};
@@ -1590,4 +1602,97 @@ sub get_backup_volumes {
     return $return_volumes;
 }
 
+sub update_net_ip {
+    my ($hostname, $net, $oldnet) = @_;
+
+    return if !$have_sdn;
+
+    my $oldbridge = $oldnet->{bridge};
+    my $bridge = $net->{bridge};
+
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+
+    return if !keys %{$subnets};
+
+    eval {
+	if (!$net->{ip}) {
+	    $net->{ip} = PVE::Network::SDN::Vnets::get_next_free_ip($bridge, $hostname);
+	    #writeconfig ?
+	} elsif ($net->{ip} ne 'dhcp' && $net->{ip} ne 'manual') {
+	    PVE::Network::SDN::Vnets::add_ip($bridge, $net->{ip}, $hostname) if $net->{ip} ne $oldnet->{ip};
+	    #writeconfig ?
+	}
+    };
+    if ($@) {
+	#keep old config if error
+	$net->{ip} = $oldnet->{ip};
+	die $@;
+    }
+
+    #delete old ip after adding new
+    if ($oldnet->{ip} && $oldnet->{ip} ne 'dhcp' && $oldnet->{ip} ne 'manual') {
+	my $deletebridge = $oldbridge ne $bridge ? $oldbridge : $bridge;
+	eval {
+	    PVE::Network::SDN::Vnets::del_ip($deletebridge, $oldnet->{ip}, $hostname) if !$net->{ip} || $net->{ip} ne $oldnet->{ip};
+	    #writeconfig ?
+	};
+	warn $@ if $@;
+    }
+
+
+    eval {
+	if (!$net->{ip6}) {
+	    $net->{ip6} = PVE::Network::SDN::Vnets::get_next_free_ip($bridge, $hostname, 6);
+	    #writeconfig ?
+	} elsif ($net->{ip6} ne 'dhcp' && $net->{ip6} ne 'manual' && $net->{ip6} ne 'auto') {
+	    PVE::Network::SDN::Vnets::add_ip($bridge, $net->{ip6}, $hostname) if $net->{ip6} ne $oldnet->{ip6};
+	    #writeconfig ?
+	}
+    };
+    if ($@) {
+	#keep old config if error
+	$net->{ip6} = $oldnet->{ip6};
+	die $@;
+    }
+
+    #delete old ip after adding new
+    if ($oldnet->{ip6} && $oldnet->{ip6} ne 'dhcp' && $oldnet->{ip6} ne 'manual' && $net->{ip6} ne 'auto') {
+	my $deletebridge = $oldbridge ne $bridge ? $oldbridge : $bridge;
+	eval {
+	    PVE::Network::SDN::Vnets::del_ip($deletebridge, $oldnet->{ip6}, $hostname) if !$net->{ip6} || $net->{ip6} ne $oldnet->{ip6};
+	    #writeconfig ?
+	};
+	warn $@ if $@;
+    }
+
+    if ($net->{ip}) {
+	my ($ip, undef) = split(/\//, $net->{ip});
+	my ($subnetidv4, $subnetv4) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets);
+	$net->{gw} = $subnetv4->{gateway};
+    }
+
+    if ($net->{ip6}) {
+	my ($ip6, undef) = split(/\//, $net->{ip6});
+	my ($subnetidv6, $subnetv6) = PVE::Network::SDN::Subnets::find_ip_subnet($ip6, $subnets);
+	$net->{gw6} = $subnetv6->{gateway} if !$net->{gw6};
+    }
+
+}
+
+sub delete_net_ip {
+    my ($hostname, $net) = @_;
+
+    return if !$have_sdn;
+
+    my $bridge = $net->{bridge};
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+    return if !keys %{$subnets};
+
+    if ($net->{ip6} && ($net->{ip6} eq 'auto' || $net->{ip6} eq 'manual' || $net->{ip6} eq 'dhcp')) {
+	PVE::Network::SDN::Vnets::del_ip($hostname, $bridge, $net->{ip6});
+    } elsif ($net->{ip} && $net->{ip} ne 'dhcp' && $net->{ip} ne 'manual') {
+	PVE::Network::SDN::Vnets::del_ip($hostname, $bridge, $net->{ip});
+    }
+}
+
 1;
-- 
2.20.1




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-09-24  8:58 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-24 16:49 [pve-devel] [PATCH v2 pve-container] POC : add/del/update ip from vnet-subnet-ipam Alexandre Derumier
2020-09-07 16:40 ` Thomas Lamprecht
2020-09-08  3:52   ` Alexandre DERUMIER
2020-09-08  7:44     ` Thomas Lamprecht
2020-09-08  8:58       ` Alexandre DERUMIER
2020-09-11  2:27         ` Alexandre DERUMIER
2020-09-24  8:58           ` Alexandre DERUMIER

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal