Implements PUT on subnet.allocation_pools
RM7209
This commit is contained in:
@@ -70,6 +70,24 @@ def _validate_subnet_cidr(context, network_id, new_subnet_cidr):
|
||||
raise exceptions.InvalidInput(error_message=err_msg)
|
||||
|
||||
|
||||
def _get_exclude_cidrs_from_allocation_pools(subnet_db, allocation_pools):
|
||||
subnet_net = netaddr.IPNetwork(subnet_db["cidr"])
|
||||
cidrset = netaddr.IPSet(
|
||||
netaddr.IPRange(
|
||||
netaddr.IPAddress(subnet_net.first),
|
||||
netaddr.IPAddress(subnet_net.last)).cidrs())
|
||||
for p in allocation_pools:
|
||||
start = netaddr.IPAddress(p["start"])
|
||||
end = netaddr.IPAddress(p["end"])
|
||||
cidrset -= netaddr.IPSet(netaddr.IPRange(
|
||||
netaddr.IPAddress(start),
|
||||
netaddr.IPAddress(end)).cidrs())
|
||||
default_cidrset = models.IPPolicy.get_ip_policy_cidrs(subnet_db)
|
||||
cidrset.update(default_cidrset)
|
||||
cidrs = [str(x.cidr) for x in cidrset.iter_cidrs()]
|
||||
return cidrs
|
||||
|
||||
|
||||
def create_subnet(context, subnet):
|
||||
"""Create a subnet.
|
||||
|
||||
@@ -143,20 +161,8 @@ def create_subnet(context, subnet):
|
||||
context, ip=netaddr.IPAddress(dns_ip)))
|
||||
|
||||
if isinstance(allocation_pools, list) and allocation_pools:
|
||||
subnet_net = netaddr.IPNetwork(new_subnet["cidr"])
|
||||
cidrset = netaddr.IPSet(
|
||||
netaddr.IPRange(
|
||||
netaddr.IPAddress(subnet_net.first),
|
||||
netaddr.IPAddress(subnet_net.last)).cidrs())
|
||||
for p in allocation_pools:
|
||||
start = netaddr.IPAddress(p["start"])
|
||||
end = netaddr.IPAddress(p["end"])
|
||||
cidrset -= netaddr.IPSet(netaddr.IPRange(
|
||||
netaddr.IPAddress(start),
|
||||
netaddr.IPAddress(end)).cidrs())
|
||||
default_cidrset = models.IPPolicy.get_ip_policy_cidrs(new_subnet)
|
||||
cidrset.update(default_cidrset)
|
||||
cidrs = [str(x.cidr) for x in cidrset.iter_cidrs()]
|
||||
cidrs = _get_exclude_cidrs_from_allocation_pools(
|
||||
new_subnet, allocation_pools)
|
||||
new_subnet["ip_policy"] = db_api.ip_policy_create(context,
|
||||
exclude=cidrs)
|
||||
|
||||
@@ -193,9 +199,10 @@ def update_subnet(context, id, subnet):
|
||||
|
||||
s = subnet["subnet"]
|
||||
|
||||
dns_ips = s.pop("dns_nameservers", [])
|
||||
host_routes = s.pop("host_routes", [])
|
||||
gateway_ip = s.pop("gateway_ip", None)
|
||||
dns_ips = utils.pop_param(s, "dns_nameservers", [])
|
||||
host_routes = utils.pop_param(s, "host_routes", [])
|
||||
gateway_ip = utils.pop_param(s, "gateway_ip", None)
|
||||
allocation_pools = utils.pop_param(s, "allocation_pools", None)
|
||||
|
||||
if gateway_ip:
|
||||
default_route = None
|
||||
@@ -229,6 +236,16 @@ def update_subnet(context, id, subnet):
|
||||
subnet_db["routes"].append(db_api.route_create(
|
||||
context, cidr=route["destination"], gateway=route["nexthop"]))
|
||||
|
||||
if isinstance(allocation_pools, list) and allocation_pools:
|
||||
cidrs = _get_exclude_cidrs_from_allocation_pools(
|
||||
subnet_db, allocation_pools)
|
||||
if subnet_db["ip_policy"]:
|
||||
subnet_db["ip_policy"] = db_api.ip_policy_update(
|
||||
context, subnet_db["ip_policy"], exclude=cidrs)
|
||||
else:
|
||||
subnet_db["ip_policy"] = db_api.ip_policy_create(
|
||||
context, exclude=cidrs)
|
||||
|
||||
subnet = db_api.subnet_update(context, subnet_db, **s)
|
||||
return v._make_subnet_dict(subnet)
|
||||
|
||||
|
@@ -698,7 +698,7 @@ class TestQuarkUpdateSubnet(test_quark_plugin.TestQuarkPlugin):
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, host_routes=None, new_routes=None, find_routes=True,
|
||||
new_dns_servers=None):
|
||||
new_dns_servers=None, new_ip_policy=None, ip_version=4):
|
||||
if host_routes is None:
|
||||
host_routes = []
|
||||
if new_routes:
|
||||
@@ -710,12 +710,21 @@ class TestQuarkUpdateSubnet(test_quark_plugin.TestQuarkPlugin):
|
||||
new_dns_servers = [models.DNSNameserver(
|
||||
ip=ip,
|
||||
subnet_id=1) for ip in new_dns_servers]
|
||||
if new_ip_policy:
|
||||
exc = [models.IPPolicyCIDR(cidr=excluded_cidr)
|
||||
for excluded_cidr in new_ip_policy]
|
||||
new_ip_policy = models.IPPolicy(exclude=exc)
|
||||
|
||||
if ip_version == 4:
|
||||
cidr = "172.16.0.0/24"
|
||||
else:
|
||||
cidr = "2607:f0d0:1002:51::0/64"
|
||||
subnet = dict(
|
||||
id=1,
|
||||
network_id=1,
|
||||
tenant_id=self.context.tenant_id, ip_version=4,
|
||||
cidr="172.16.0.0/24",
|
||||
tenant_id=self.context.tenant_id,
|
||||
ip_version=ip_version,
|
||||
cidr=cidr,
|
||||
host_routes=host_routes,
|
||||
dns_nameservers=["4.2.2.1", "4.2.2.2"],
|
||||
enable_dhcp=None)
|
||||
@@ -752,6 +761,8 @@ class TestQuarkUpdateSubnet(test_quark_plugin.TestQuarkPlugin):
|
||||
new_subnet_mod["routes"] = new_routes
|
||||
if new_dns_servers:
|
||||
new_subnet_mod["dns_nameservers"] = new_dns_servers
|
||||
if new_ip_policy:
|
||||
new_subnet_mod["ip_policy"] = new_ip_policy
|
||||
subnet_update.return_value = new_subnet_mod
|
||||
yield dns_create, route_update, route_create
|
||||
|
||||
@@ -852,6 +863,72 @@ class TestQuarkUpdateSubnet(test_quark_plugin.TestQuarkPlugin):
|
||||
self.assertEqual(len(res["host_routes"]), 0)
|
||||
self.assertEqual(res["gateway_ip"], "4.3.2.1")
|
||||
|
||||
def test_update_subnet_allocation_pools_zero(self):
|
||||
with self._stubs() as (dns_create, route_update, route_create):
|
||||
resp = self.plugin.update_subnet(self.context, 1,
|
||||
dict(subnet=dict()))
|
||||
self.assertEqual(resp["allocation_pools"],
|
||||
[dict(start="172.16.0.1", end="172.16.0.254")])
|
||||
|
||||
def test_update_subnet_allocation_pools_one(self):
|
||||
pools = [dict(start="172.16.0.10", end="172.16.0.20")]
|
||||
s = dict(subnet=dict(allocation_pools=pools))
|
||||
with self._stubs(
|
||||
new_ip_policy=[
|
||||
'172.16.0.0/29', '172.16.0.8/31', '172.16.0.21/32',
|
||||
'172.16.0.22/31', '172.16.0.24/29', '172.16.0.32/27',
|
||||
'172.16.0.64/26', '172.16.0.128/25']
|
||||
) as (dns_create, route_update, route_create):
|
||||
resp = self.plugin.update_subnet(self.context, 1, s)
|
||||
self.assertEqual(resp["allocation_pools"], pools)
|
||||
|
||||
def test_update_subnet_allocation_pools_two(self):
|
||||
pools = [dict(start="172.16.0.10", end="172.16.0.20"),
|
||||
dict(start="172.16.0.40", end="172.16.0.50")]
|
||||
s = dict(subnet=dict(allocation_pools=pools))
|
||||
with self._stubs(
|
||||
new_ip_policy=[
|
||||
'172.16.0.0/29', '172.16.0.8/31', '172.16.0.21/32',
|
||||
'172.16.0.22/31', '172.16.0.24/29', '172.16.0.32/29',
|
||||
'172.16.0.51/32', '172.16.0.52/30', '172.16.0.56/29',
|
||||
'172.16.0.64/26', '172.16.0.128/25']
|
||||
) as (dns_create, route_update, route_create):
|
||||
resp = self.plugin.update_subnet(self.context, 1, s)
|
||||
self.assertEqual(resp["allocation_pools"], pools)
|
||||
|
||||
def test_update_subnet_allocation_pools_three(self):
|
||||
pools = [dict(start="172.16.0.5", end="172.16.0.254")]
|
||||
s = dict(subnet=dict(allocation_pools=pools))
|
||||
with self._stubs(
|
||||
new_ip_policy=['172.16.0.0/30', '172.16.0.4/32', '172.16.0.255/32']
|
||||
) as (dns_create, route_update, route_create):
|
||||
resp = self.plugin.update_subnet(self.context, 1, s)
|
||||
self.assertEqual(resp["allocation_pools"], pools)
|
||||
|
||||
def test_create_subnet_allocation_pools_four(self):
|
||||
pools = [dict(start="2607:f0d0:1002:51::a",
|
||||
end="2607:f0d0:1002:51:ffff:ffff:ffff:fffe")]
|
||||
s = dict(subnet=dict(allocation_pools=pools))
|
||||
with self._stubs(
|
||||
ip_version=6,
|
||||
new_ip_policy=[
|
||||
'2607:f0d0:1002:51::/125', '2607:f0d0:1002:51::8/127',
|
||||
'2607:f0d0:1002:51:ffff:ffff:ffff:ffff/128']
|
||||
) as (dns_create, route_update, route_create):
|
||||
resp = self.plugin.update_subnet(self.context, 1, s)
|
||||
self.assertEqual(resp["allocation_pools"], pools)
|
||||
|
||||
def test_update_subnet_allocation_pools_empty_list(self):
|
||||
pools = []
|
||||
s = dict(subnet=dict(allocation_pools=pools))
|
||||
with self._stubs(
|
||||
new_ip_policy=[]
|
||||
) as (dns_create, route_update, route_create):
|
||||
resp = self.plugin.update_subnet(self.context, 1, s)
|
||||
expected_pools = [{'start': '172.16.0.1',
|
||||
'end': '172.16.0.254'}]
|
||||
self.assertEqual(resp["allocation_pools"], expected_pools)
|
||||
|
||||
|
||||
class TestQuarkDeleteSubnet(test_quark_plugin.TestQuarkPlugin):
|
||||
@contextlib.contextmanager
|
||||
|
Reference in New Issue
Block a user