Fix errors when throwing floating ip exceptions. Add check if port already has flip on update

This commit is contained in:
Alan Quillin
2016-02-10 20:17:18 -05:00
parent de378ce04c
commit cc1af30150
3 changed files with 84 additions and 38 deletions

View File

@@ -151,36 +151,36 @@ class FloatingIpNotFound(exceptions.NotFound):
class RemoveFloatingIpFailure(exceptions.NeutronException): class RemoveFloatingIpFailure(exceptions.NeutronException):
message = _("An error occurred when trying to remove the " message = _("An error occurred when trying to remove the "
"floating IP %(id).") "floating IP %(id)s.")
class RegisterFloatingIpFailure(exceptions.NeutronException): class RegisterFloatingIpFailure(exceptions.NeutronException):
message = _("An error occurred when trying to register the floating IP " message = _("An error occurred when trying to register the floating IP "
"%(id).") "%(id)s.")
class PortAlreadyContainsFloatingIp(exceptions.Conflict): class PortAlreadyContainsFloatingIp(exceptions.Conflict):
message = _("Port %(port_id) already has an associated floating IP.") message = _("Port %(port_id)s already has an associated floating IP.")
class FixedIpDoesNotExistsForPort(exceptions.BadRequest): class FixedIpDoesNotExistsForPort(exceptions.BadRequest):
message = _("Fixed IP %(fixed_ip) does not exist on Port %(port_id)") message = _("Fixed IP %(fixed_ip)s does not exist on Port %(port_id)")
class NoAvailableFixedIPsForPort(exceptions.Conflict): class NoAvailableFixedIpsForPort(exceptions.Conflict):
message = _("There are no available fixed IPs for port %(port_id)") message = _("There are no available fixed IPs for port %(port_id)s")
class PortDoesNotHaveAGateway(exceptions.Conflict): class PortDoesNotHaveAGateway(exceptions.Conflict):
message = _("Port %(port_id) does not have a gateway") message = _("Port %(port_id)s does not have a gateway")
class PortAlreadyAssociatedToFloatingIP(exceptions.BadRequest): class PortAlreadyAssociatedToFloatingIp(exceptions.BadRequest):
message = _("Port %(port_id) is already associated with " message = _("Port %(port_id)s is already associated with "
"floating IP %(flip_id)") "floating IP %(flip_id)s")
class FloatingIPUpdateNoPortIdSupplied(exceptions.BadRequest): class FloatingIpUpdateNoPortIdSupplied(exceptions.BadRequest):
message = _("When no port is currently associated to the floating IP, " message = _("When no port is currently associated to the floating IP, "
"port_id is required but was not supplied") "port_id is required but was not supplied")

View File

@@ -81,12 +81,12 @@ def create_floatingip(context, content):
raise exceptions.PortNotFound(port_id=port_id) raise exceptions.PortNotFound(port_id=port_id)
if not port.ip_addresses or len(port.ip_addresses) == 0: if not port.ip_addresses or len(port.ip_addresses) == 0:
raise qex.NoAvailableFixedIPsForPort(port_id=port_id) raise qex.NoAvailableFixedIpsForPort(port_id=port_id)
if not fixed_ip_address: if not fixed_ip_address:
fixed_ip = _get_next_available_fixed_ip(port) fixed_ip = _get_next_available_fixed_ip(port)
if not fixed_ip: if not fixed_ip:
raise qex.NoAvailableFixedIPsForPort( raise qex.NoAvailableFixedIpsForPort(
port_id=port_id) port_id=port_id)
else: else:
fixed_ip = next((ip for ip in port.ip_addresses fixed_ip = next((ip for ip in port.ip_addresses
@@ -175,21 +175,25 @@ def update_floatingip(context, id, content):
current_port = current_ports[0] current_port = current_ports[0]
if not port_id and not current_port: if not port_id and not current_port:
raise qex.FloatingIPUpdateNoPortIdSupplied() raise qex.FloatingIpUpdateNoPortIdSupplied()
if port_id: if port_id:
port = db_api.port_find(context, id=port_id, scope=db_api.ONE) port = db_api.port_find(context, id=port_id, scope=db_api.ONE)
if not port: if not port:
raise exceptions.PortNotFound(port_id=port_id) raise exceptions.PortNotFound(port_id=port_id)
if any(ip for ip in port.ip_addresses
if (ip.get('address_type') == ip_types.FLOATING)):
raise qex.PortAlreadyContainsFloatingIp(port_id=port_id)
if current_port and current_port.id == port_id: if current_port and current_port.id == port_id:
d = dict(flip_id=id, port_id=port_id) d = dict(flip_id=id, port_id=port_id)
raise qex.PortAlreadyAssociatedToFloatingIP(**d) raise qex.PortAlreadyAssociatedToFloatingIp(**d)
fixed_ip = _get_next_available_fixed_ip(port) fixed_ip = _get_next_available_fixed_ip(port)
LOG.info('new fixed ip: %s' % fixed_ip) LOG.info('new fixed ip: %s' % fixed_ip)
if not fixed_ip: if not fixed_ip:
raise qex.NoAvailableFixedIPsForPort(port_id=port_id) raise qex.NoAvailableFixedIpsForPort(port_id=port_id)
LOG.info('current ports: %s' % current_ports) LOG.info('current ports: %s' % current_ports)

View File

@@ -195,8 +195,8 @@ class TestCreateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
for ip in ips: for ip in ips:
ip_model = models.IPAddress() ip_model = models.IPAddress()
ip_model.update(ip) ip_model.update(ip)
if (ip["address_type"] == "floating" addr_type = ip.get("address_type")
and "fixed_ip_addr" in ip): if addr_type == "floating" and "fixed_ip_addr" in ip:
fixed_ip = models.IPAddress() fixed_ip = models.IPAddress()
fixed_ip.update(next(ip_addr for ip_addr in ips fixed_ip.update(next(ip_addr for ip_addr in ips
if (ip_addr["address_readable"] == if (ip_addr["address_readable"] ==
@@ -426,7 +426,7 @@ class TestCreateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
with self._stubs(port=port, network=network): with self._stubs(port=port, network=network):
with self.assertRaises( with self.assertRaises(
q_ex.NoAvailableFixedIPsForPort): q_ex.NoAvailableFixedIpsForPort):
request = dict(floating_network_id=network["id"], request = dict(floating_network_id=network["id"],
port_id=port["id"]) port_id=port["id"])
self.plugin.create_floatingip(self.context, self.plugin.create_floatingip(self.context,
@@ -455,7 +455,7 @@ class TestCreateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
with self._stubs(port=port, ips=ips, network=network): with self._stubs(port=port, ips=ips, network=network):
with self.assertRaises( with self.assertRaises(
q_ex.NoAvailableFixedIPsForPort): q_ex.NoAvailableFixedIpsForPort):
request = dict(floating_network_id=network["id"], request = dict(floating_network_id=network["id"],
port_id=port["id"]) port_id=port["id"])
self.plugin.create_floatingip(self.context, self.plugin.create_floatingip(self.context,
@@ -464,7 +464,7 @@ class TestCreateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin): class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
@contextlib.contextmanager @contextlib.contextmanager
def _stubs(self, flip=None, curr_port=None, new_port=None): def _stubs(self, flip=None, curr_port=None, new_port=None, ips=None):
curr_port_model = None curr_port_model = None
if curr_port: if curr_port:
curr_port_model = models.Port() curr_port_model = models.Port()
@@ -474,16 +474,18 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
if new_port: if new_port:
new_port_model = models.Port() new_port_model = models.Port()
new_port_model.update(new_port) new_port_model.update(new_port)
fixed_ips = new_port.get("fixed_ips") if ips:
if fixed_ips: for ip in ips:
new_port_model.ip_addresses = [] ip_model = models.IPAddress()
for ip in fixed_ips: ip_model.update(ip)
addr = netaddr.IPAddress(ip) addr_type = ip.get("address_type")
fixed_ip_model = models.IPAddress() if addr_type == "floating" and "fixed_ip_addr" in ip:
fixed_ip_model.update(dict(address_readable=ip, fixed_ip = models.IPAddress()
address=int(addr), version=4, fixed_ip.update(next(ip_addr for ip_addr in ips
address_type="fixed")) if (ip_addr["address_readable"] ==
new_port_model.ip_addresses.append(fixed_ip_model) ip["fixed_ip_addr"])))
ip_model.fixed_ip = fixed_ip
new_port_model.ip_addresses.append(ip_model)
flip_model = None flip_model = None
if flip: if flip:
@@ -546,12 +548,21 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
yield yield
def test_update_with_new_port_and_no_previous_port(self): def test_update_with_new_port_and_no_previous_port(self):
new_port = dict(id="2", fixed_ips=["192.168.0.1"]) new_port = dict(id="2")
fixed_ip_addr = netaddr.IPAddress("192.168.0.1")
fixed_ip = dict(address_type="fixed", version=4,
address=int(fixed_ip_addr),
address_readable=str(fixed_ip_addr),
allocated_at=datetime.datetime.now())
ips = [fixed_ip]
addr = netaddr.IPAddress("10.0.0.1") addr = netaddr.IPAddress("10.0.0.1")
flip = dict(id="3", fixed_ip_address="172.16.1.1", address=int(addr), flip = dict(id="3", fixed_ip_address="172.16.1.1", address=int(addr),
address_readable=str(addr)) address_readable=str(addr))
with self._stubs(flip=flip, new_port=new_port): with self._stubs(flip=flip, new_port=new_port, ips=ips):
content = dict(port_id=new_port["id"]) content = dict(port_id=new_port["id"])
ret = self.plugin.update_floatingip(self.context, flip["id"], ret = self.plugin.update_floatingip(self.context, flip["id"],
dict(floatingip=content)) dict(floatingip=content))
@@ -560,12 +571,21 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
def test_update_with_new_port(self): def test_update_with_new_port(self):
curr_port = dict(id="1") curr_port = dict(id="1")
new_port = dict(id="2", fixed_ips=["192.168.0.1"]) new_port = dict(id="2")
fixed_ip_addr = netaddr.IPAddress("192.168.0.1")
fixed_ip = dict(address_type="fixed", version=4,
address=int(fixed_ip_addr),
address_readable=str(fixed_ip_addr),
allocated_at=datetime.datetime.now())
ips = [fixed_ip]
addr = netaddr.IPAddress("10.0.0.1") addr = netaddr.IPAddress("10.0.0.1")
flip = dict(id="3", fixed_ip_address="172.16.1.1", address=int(addr), flip = dict(id="3", fixed_ip_address="172.16.1.1", address=int(addr),
address_readable=str(addr)) address_readable=str(addr))
with self._stubs(flip=flip, curr_port=curr_port, new_port=new_port): with self._stubs(flip=flip, curr_port=curr_port,
new_port=new_port, ips=ips):
content = dict(port_id=new_port["id"]) content = dict(port_id=new_port["id"])
ret = self.plugin.update_floatingip(self.context, flip["id"], ret = self.plugin.update_floatingip(self.context, flip["id"],
dict(floatingip=content)) dict(floatingip=content))
@@ -603,7 +623,7 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
address_readable=str(addr)) address_readable=str(addr))
with self._stubs(flip=flip, new_port=new_port): with self._stubs(flip=flip, new_port=new_port):
with self.assertRaises(q_ex.NoAvailableFixedIPsForPort): with self.assertRaises(q_ex.NoAvailableFixedIpsForPort):
content = dict(port_id="123") content = dict(port_id="123")
self.plugin.update_floatingip(self.context, flip["id"], self.plugin.update_floatingip(self.context, flip["id"],
dict(floatingip=content)) dict(floatingip=content))
@@ -616,7 +636,29 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
address_readable=str(addr)) address_readable=str(addr))
with self._stubs(flip=flip, new_port=new_port, curr_port=curr_port): with self._stubs(flip=flip, new_port=new_port, curr_port=curr_port):
with self.assertRaises(q_ex.PortAlreadyAssociatedToFloatingIP): with self.assertRaises(q_ex.PortAlreadyAssociatedToFloatingIp):
content = dict(port_id="123")
self.plugin.update_floatingip(self.context, flip["id"],
dict(floatingip=content))
def test_update_when_port_has_a_different_flip_should_fail(self):
new_port = dict(id="123")
floating_ip_addr = netaddr.IPAddress("192.168.0.1")
floating_ip = dict(address_type="floating", version=4,
address=int(floating_ip_addr),
address_readable=str(floating_ip_addr),
allocated_at=datetime.datetime.now())
ips = [floating_ip]
curr_port = dict(id="456")
addr = netaddr.IPAddress("10.0.0.1")
flip = dict(id="3", fixed_ip_address="172.16.1.1", address=int(addr),
address_readable=str(addr))
with self._stubs(flip=flip, new_port=new_port,
curr_port=curr_port, ips=ips):
with self.assertRaises(q_ex.PortAlreadyContainsFloatingIp):
content = dict(port_id="123") content = dict(port_id="123")
self.plugin.update_floatingip(self.context, flip["id"], self.plugin.update_floatingip(self.context, flip["id"],
dict(floatingip=content)) dict(floatingip=content))
@@ -627,7 +669,7 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
address_readable=str(addr)) address_readable=str(addr))
with self._stubs(flip=flip): with self._stubs(flip=flip):
with self.assertRaises(q_ex.FloatingIPUpdateNoPortIdSupplied): with self.assertRaises(q_ex.FloatingIpUpdateNoPortIdSupplied):
content = dict(port_id=None) content = dict(port_id=None)
self.plugin.update_floatingip(self.context, flip["id"], self.plugin.update_floatingip(self.context, flip["id"],
dict(floatingip=content)) dict(floatingip=content))