Merge "Block flip update if fixed ip conflicts with gw."
This commit is contained in:
commit
15671d45ef
@ -204,6 +204,11 @@ class PortAlreadyContainsFloatingIp(n_exc.Conflict):
|
||||
message = _("Port %(port_id)s already has an associated floating IP.")
|
||||
|
||||
|
||||
class FixedIpAllocatedToGatewayIp(n_exc.Conflict):
|
||||
message = _("Gateway IP of Floating IP subnet conflicts with Fixed IP "
|
||||
"allocated to port %(port_id)s of network %(network_id)s.")
|
||||
|
||||
|
||||
class FixedIpDoesNotExistsForPort(n_exc.BadRequest):
|
||||
message = _("Fixed IP %(fixed_ip)s does not exist on Port %(port_id)s")
|
||||
|
||||
|
@ -220,6 +220,27 @@ def _update_flip(context, flip_id, ip_type, requested_ports):
|
||||
not curr_port_ids and not req_port_ids):
|
||||
raise q_exc.FloatingIpUpdateNoPortIdSupplied()
|
||||
|
||||
# Validate that GW IP is not in use on the NW.
|
||||
flip_subnet = v._make_subnet_dict(flip.subnet)
|
||||
for added_port_id in added_port_ids:
|
||||
port = _get_port(context, added_port_id)
|
||||
nw = port.network
|
||||
nw_ports = v._make_ports_list(nw.ports)
|
||||
fixed_ips = [ip.get('ip_address') for p in nw_ports
|
||||
for ip in p.get('fixed_ips')]
|
||||
|
||||
gw_ip = flip_subnet.get('gateway_ip')
|
||||
if gw_ip in fixed_ips:
|
||||
port_with_gateway_ip = None
|
||||
for port in nw_ports:
|
||||
for ip in port.get('fixed_ips'):
|
||||
if gw_ip in ip.get('ip_address'):
|
||||
port_with_gateway_ip = port
|
||||
break
|
||||
port_id = port_with_gateway_ip.get('id')
|
||||
network_id = port_with_gateway_ip.get('network_id')
|
||||
raise q_exc.FixedIpAllocatedToGatewayIp(port_id=port_id,
|
||||
network_id=network_id)
|
||||
port_fixed_ips = {}
|
||||
|
||||
# Keep the ports and fixed ips that have not changed
|
||||
|
@ -104,7 +104,7 @@ def _make_subnet_dict(subnet, fields=None):
|
||||
|
||||
if (CONF.QUARK.show_allocation_pools and not
|
||||
STRATEGY.is_provider_subnet(subnet_id)):
|
||||
res["allocation_pools"] = subnet.allocation_pools
|
||||
res["allocation_pools"] = subnet.get('allocation_pools', [])
|
||||
else:
|
||||
res["allocation_pools"] = []
|
||||
|
||||
|
@ -485,7 +485,8 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
|
||||
self.addCleanup(reset_refresh, self.context)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, flip=None, curr_port=None, new_port=None, ips=None):
|
||||
def _stubs(self, flip=None, curr_port=None, new_port=None, ips=None,
|
||||
subnet=None, network=None):
|
||||
curr_port_model = None
|
||||
if curr_port:
|
||||
curr_port_model = models.Port()
|
||||
@ -508,10 +509,20 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
|
||||
ip_model.fixed_ip = fixed_ip
|
||||
new_port_model.ip_addresses.append(ip_model)
|
||||
|
||||
subnet_model = None
|
||||
if subnet:
|
||||
subnet_model = models.Subnet()
|
||||
subnet_model.update(subnet)
|
||||
else:
|
||||
subnet_model = models.Subnet(id=1, network_id=1, name=1,
|
||||
tenant_id=1, ip_version=4,
|
||||
dns_nameservers=[],
|
||||
cidr="192.168.0.0/24")
|
||||
flip_model = None
|
||||
if flip:
|
||||
flip_model = models.IPAddress()
|
||||
flip_model.update(flip)
|
||||
flip_model.subnet = subnet_model
|
||||
if curr_port_model:
|
||||
flip_model.ports = [curr_port_model]
|
||||
fixed_ip = flip.get("fixed_ip_address")
|
||||
@ -523,6 +534,11 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
|
||||
address_type="fixed"))
|
||||
flip_model.fixed_ip = fixed_ip_model
|
||||
|
||||
net_model = models.Network()
|
||||
if network:
|
||||
net_model.update(network)
|
||||
net_model.ports = [new_port_model]
|
||||
|
||||
def _find_port(context, id, **kwargs):
|
||||
return (curr_port_model if (curr_port_model and
|
||||
id == curr_port_model.id)
|
||||
@ -551,6 +567,8 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
|
||||
|
||||
with contextlib.nested(
|
||||
mock.patch("quark.db.api.floating_ip_find"),
|
||||
mock.patch("quark.db.api.network_find"),
|
||||
mock.patch("quark.db.api.subnet_find"),
|
||||
mock.patch("quark.db.api.port_find"),
|
||||
mock.patch("quark.drivers.unicorn_driver.UnicornDriver"
|
||||
".register_floating_ip"),
|
||||
@ -563,9 +581,12 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
|
||||
mock.patch("quark.db.api.floating_ip_associate_fixed_ip"),
|
||||
mock.patch("quark.db.api.floating_ip_disassociate_fixed_ip"),
|
||||
mock.patch("quark.billing.notify")
|
||||
) as (flip_find, port_find, reg_flip, update_flip, rem_flip,
|
||||
port_assoc, port_dessoc, flip_assoc, flip_dessoc, notify):
|
||||
) as (flip_find, net_find, subnet_find, port_find, reg_flip,
|
||||
update_flip, rem_flip, port_assoc, port_dessoc, flip_assoc,
|
||||
flip_dessoc, notify):
|
||||
flip_find.return_value = flip_model
|
||||
net_find.return_value = net_model
|
||||
subnet_find.return_value = subnet_model
|
||||
port_find.side_effect = _find_port
|
||||
port_assoc.side_effect = _port_assoc
|
||||
port_dessoc.side_effect = _port_dessoc
|
||||
@ -576,6 +597,35 @@ class TestUpdateFloatingIPs(test_quark_plugin.TestQuarkPlugin):
|
||||
# arguments it was called.
|
||||
yield notify
|
||||
|
||||
def test_update_with_conflicted_fixed_ip_and_gateway(self):
|
||||
floating_ip_addr = netaddr.IPAddress("10.0.0.1")
|
||||
flip = dict(id=1, address=int(floating_ip_addr), version=4,
|
||||
address_readable=str(floating_ip_addr), subnet_id=1,
|
||||
network_id=2, used_by_tenant_id=1)
|
||||
network = dict(id="00000000-0000-0000-0000-000000000000",
|
||||
ipam_strategy="ANY")
|
||||
subnet = dict(id=1, network_id=1, name=1,
|
||||
tenant_id=1, ip_version=4,
|
||||
routes=[models.Route(cidr='0.0.0.0',
|
||||
gateway='192.168.0.1')],
|
||||
cidr="192.168.0.0/24",
|
||||
dns_nameservers=[],
|
||||
enable_dhcp=None)
|
||||
|
||||
fixed_ip_addr = netaddr.IPAddress("192.168.0.1")
|
||||
fixed_ips = [dict(address_type="fixed", address=int(fixed_ip_addr),
|
||||
version=4, address_readable=str(fixed_ip_addr),
|
||||
allocated_at=datetime.datetime.now())]
|
||||
new_port = dict(id="abcdefgh-1111-2222-3333-1234567890ab")
|
||||
|
||||
with self._stubs(flip=flip, new_port=new_port,
|
||||
ips=fixed_ips, subnet=subnet, network=network):
|
||||
with self.assertRaises(
|
||||
q_ex.FixedIpAllocatedToGatewayIp):
|
||||
content = dict(port_id=new_port["id"])
|
||||
self.plugin.update_floatingip(self.context, flip["id"],
|
||||
dict(floatingip=content))
|
||||
|
||||
def test_update_with_new_port_and_no_previous_port(self):
|
||||
new_port = dict(id="2")
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user