From 5c0703c87d77be2fec62ed44df3a2d9e2e2fc224 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Tue, 13 Jan 2015 00:11:54 -0500 Subject: [PATCH] Fixes BZ #1176423: create reservation for VIP ip addresses in DHCP https://bugzilla.redhat.com/show_bug.cgi?id=1176423 For VIPs on the provisioning network (with DHCP active), calling unused_ip is insufficient. We also need to create the actual DHCP reservation so the allocated IP address won't be reused elsewhere. This change handles both reserving and freeing IP addresses. For a given VIP nic, we reserve the IP address in DHCP when initially creating this VIP on a DHCP network, or moving its network traffic type to such a network. We delete the reservation when moving the VIP *away from* a DHCP network, or on deleting it. One side effect of this is VIP creation takes still longer than before, due to the extra DHCP proxy action, but we already have a "waiting..." dialog with spinner for this step. --- app/models/staypuft/vip_nic.rb | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/app/models/staypuft/vip_nic.rb b/app/models/staypuft/vip_nic.rb index af4c0d69..73376c4d 100644 --- a/app/models/staypuft/vip_nic.rb +++ b/app/models/staypuft/vip_nic.rb @@ -3,15 +3,46 @@ class VipNic < Nic::Managed has_one :deployment_vip_nic, :dependent => :destroy, :class_name => 'Staypuft::DeploymentVipNic' has_one :deployment, :class_name => 'Staypuft::Deployment', :through => :deployment_vip_nic - before_save :reserve_ip + before_save :reserve_ip + before_destroy :release_ip # VIP nic is associated with the deployment, not the host def require_host? false end + def reserve_ip + # if changing subnets from dhcp network, clear old reservation + if self.subnet_id_changed? && self.subnet_id_was + old_subnet = Subnet.find(self.subnet_id_was) + if old_subnet && (old_subnet.ipam == Subnet::IPAM_MODES[:dhcp]) && old_subnet.dhcp? + begin + old_subnet.dhcp_proxy.delete(old_subnet.network, self.mac) + rescue ProxyAPI::ProxyException => ex + Rails.logger.error "Error removing DHCP address reservation for VIP nic #{identifier}_#{mac.delete(':')}, mac #{mac}: #{ex}" + end + end + end if self.subnet.present? && self.subnet.ipam? && (!self.ip || self.subnet_id_changed?) self.ip = self.subnet.unused_ip + if (subnet.ipam == Subnet::IPAM_MODES[:dhcp]) && subnet.dhcp? + begin + subnet.dhcp_proxy.set(subnet.network, {:mac => self.mac, :ip => self.ip, :hostname => "#{identifier}_#{mac.delete(':')}"}) + rescue ProxyAPI::ProxyException => ex + Rails.logger.error "Error reserving DHCP address for VIP nic #{identifier}_#{mac.delete(':')}, mac #{mac}: #{ex}" + end + end + end + end + + def release_ip + # if changing subnets from dhcp network, clear old reservation + if subnet.present? && (subnet.ipam == Subnet::IPAM_MODES[:dhcp]) && subnet.dhcp? + begin + subnet.dhcp_proxy.delete(subnet.network, self.mac) + rescue ProxyAPI::ProxyException => ex + Rails.logger.error "Error removing DHCP address reservation for VIP nic #{identifier}_#{mac.delete(':')}, mac #{mac}: #{ex}" + end end end end