Merge pull request #184 from asadoughi/ip_policy_size

Added size column to IPPolicy
This commit is contained in:
Jason Meridth 2014-08-06 21:09:06 -05:00
commit 40f68278f6
11 changed files with 268 additions and 75 deletions

View File

@ -120,7 +120,9 @@ def get_unused_ips(session, used_ips_counts):
ret = defaultdict(int)
for tenant_id, subnet in query.all():
net_size = netaddr.IPNetwork(subnet._cidr).size
policy_size = models.IPPolicy.get_ip_policy_cidrs(subnet).size
policy_size = (subnet["ip_policy"].size
if "ip_policy" in subnet
else 0)
ret[tenant_id] += net_size - policy_size
for tenant_id in used_ips_counts:

View File

@ -16,6 +16,7 @@
import datetime
import inspect
import netaddr
from neutron.openstack.common import log as logging
from neutron.openstack.common import timeutils
from neutron.openstack.common import uuidutils
@ -568,10 +569,12 @@ def security_group_rule_delete(context, rule):
def ip_policy_create(context, **ip_policy_dict):
new_policy = models.IPPolicy()
exclude = ip_policy_dict.pop("exclude")
ip_set = netaddr.IPSet()
for excluded_cidr in exclude:
new_policy["exclude"].append(
models.IPPolicyCIDR(cidr=excluded_cidr))
ip_set.add(excluded_cidr)
ip_policy_dict["size"] = ip_set.size
new_policy.update(ip_policy_dict)
new_policy["tenant_id"] = context.tenant_id
context.session.add(new_policy)
@ -589,9 +592,12 @@ def ip_policy_update(context, ip_policy, **ip_policy_dict):
exclude = ip_policy_dict.pop("exclude", [])
if exclude:
ip_policy["exclude"] = []
for excluded_cidr in exclude:
ip_policy["exclude"].append(
models.IPPolicyCIDR(cidr=excluded_cidr))
ip_set = netaddr.IPSet()
for excluded_cidr in exclude:
ip_policy["exclude"].append(
models.IPPolicyCIDR(cidr=excluded_cidr))
ip_set.add(excluded_cidr)
ip_policy_dict["size"] = ip_set.size
ip_policy.update(ip_policy_dict)
context.session.add(ip_policy)

View File

@ -0,0 +1,50 @@
"""Populate IPPolicy.size
Revision ID: 28e55acaf366
Revises: 3d22de205729
Create Date: 2014-08-06 14:50:04.022331
"""
# revision identifiers, used by Alembic.
revision = '28e55acaf366'
down_revision = '3d22de205729'
from alembic import op
from sqlalchemy.sql import column, select, table
import netaddr
import sqlalchemy as sa
from quark.db.custom_types import INET
def upgrade():
ip_policy = table('quark_ip_policy',
column('id', sa.String(length=36)),
column('size', INET()))
ip_policy_cidrs = table('quark_ip_policy_cidrs',
column('ip_policy_id', sa.String(length=36)),
column('cidr', sa.String(length=64)))
connection = op.get_bind()
# 1. Retrieve all ip_policy_cidr rows.
results = connection.execute(
select([ip_policy_cidrs.c.ip_policy_id, ip_policy_cidrs.c.cidr])
).fetchall()
# 2. Determine IPSet for each IP Policy.
ipp = dict()
for ip_policy_id, cidr in results:
if ip_policy_id not in ipp:
ipp[ip_policy_id] = netaddr.IPSet()
ipp[ip_policy_id].add(cidr)
# 3. Populate size for each IP Policy.
for ip_policy_id in ipp:
connection.execute(ip_policy.update().values(
size=ipp[ip_policy_id].size).where(
ip_policy.c.id == ip_policy_id))
def downgrade():
raise NotImplementedError()

View File

@ -0,0 +1,24 @@
"""Add size to quark_ip_policy
Revision ID: 3d22de205729
Revises: 2748e48cee3a
Create Date: 2014-07-04 23:53:09.531715
"""
# revision identifiers, used by Alembic.
revision = '3d22de205729'
down_revision = '3ed0c5a067f1'
from alembic import op
import sqlalchemy as sa
from quark.db.custom_types import INET
def upgrade():
op.add_column('quark_ip_policy', sa.Column('size', INET()))
def downgrade():
op.drop_column('quark_ip_policy', 'size')

View File

@ -19,12 +19,12 @@ def upgrade():
sa.Column('enabled',
sa.Boolean(),
nullable=False,
default=True))
server_default=sa.sql.expression.true()))
op.add_column('quark_mac_address_ranges',
sa.Column('do_not_use',
sa.Boolean(),
nullable=False,
default=False))
server_default=sa.sql.expression.false()))
def downgrade():

View File

@ -1 +1 @@
3ed0c5a067f1
28e55acaf366

View File

@ -374,6 +374,7 @@ class IPPolicy(BASEV2, models.HasId, models.HasTenant):
backref="ip_policy")
name = sa.Column(sa.String(255), nullable=True)
description = sa.Column(sa.String(255), nullable=True)
size = sa.Column(custom_types.INET())
@staticmethod
def get_ip_policy_cidrs(subnet):

View File

@ -490,14 +490,13 @@ class QuarkIpam(object):
ip_addr=ip_address, subnet_id=subnet["id"])
continue
ip_policy_cidrs = None
ip_policy = None
if not ip_address:
# Policies don't prevent explicit assignment, so we only
# need to check if we're allocating a new IP
ip_policy_cidrs = models.IPPolicy.get_ip_policy_cidrs(
subnet)
ip_policy = subnet.get("ip_policy")
policy_size = ip_policy_cidrs.size if ip_policy_cidrs else 0
policy_size = ip_policy["size"] if ip_policy else 0
if ipnet.size > (ips_in_subnet + policy_size - 1):
if not ip_address:

View File

@ -0,0 +1,40 @@
from neutron import context
from neutron.db import api as neutron_db_api
from oslo.config import cfg
import unittest2
from quark.db import api as db_api
from quark.db import models
class QuarkIPPoliciesFunctionalTest(unittest2.TestCase):
def setUp(self):
self.context = context.Context('fake', 'fake', is_admin=False)
super(QuarkIPPoliciesFunctionalTest, self).setUp()
cfg.CONF.set_override('connection', 'sqlite://', 'database')
neutron_db_api.configure_db()
neutron_db_api.register_models(models.BASEV2)
def tearDown(self):
neutron_db_api.unregister_models(models.BASEV2)
neutron_db_api.clear_db()
class QuarkIPPoliciesSizeTest(QuarkIPPoliciesFunctionalTest):
def test_ip_policies_create(self):
ip_policy_dict = dict(
exclude=["192.168.10.0/32", "192.168.10.255/32"])
ip_policy = db_api.ip_policy_create(self.context, **ip_policy_dict)
self.assertEqual(ip_policy["size"], 2)
def test_ip_policies_update(self):
ip_policy_dict = dict(
exclude=["192.168.10.0/32", "192.168.10.255/32"])
ip_policy = db_api.ip_policy_create(self.context, **ip_policy_dict)
ip_policy_update_dict = dict(
exclude=["192.168.10.0/32", "192.168.10.13/32",
"192.168.10.255/32"])
updated_ip_policy = db_api.ip_policy_update(
self.context, ip_policy, **ip_policy_update_dict)
self.assertEqual(updated_ip_policy["size"], 3)

View File

@ -348,12 +348,12 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
def test_allocate_new_ip_address_two_empty_subnets(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=1, network=dict(ip_policy=None),
next_auto_assign_ip=1,
ip_policy=None)
subnet6 = dict(id=1, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=self.v6_fip.value + 1,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
with self._stubs(subnets=[[(subnet4, 0)], [(subnet6, 0)]],
addresses=[None, None, None, None]):
address = []
@ -367,7 +367,7 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
def test_allocate_new_ip_address_one_v4_subnet_open(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=2, network=dict(ip_policy=None),
next_auto_assign_ip=2,
ip_policy=None)
with self._stubs(subnets=[[(subnet4, 0)], []],
addresses=[None, None, None, None]):
@ -380,7 +380,7 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
subnet6 = dict(id=1, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=self.v6_fip.value + 1,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
with self._stubs(subnets=[[], [(subnet6, 0)]],
addresses=[None, None, None, None]):
address = []
@ -402,7 +402,6 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
subnet6 = dict(id=1, first_ip=fip, last_ip=lip,
cidr="feed::/104", ip_version=6,
next_auto_assign_ip=fip + 1,
network=dict(ip_policy=None),
ip_policy=None)
network = netaddr.IPNetwork("0.0.0.0/24")
first = network.ipv6().first
@ -427,13 +426,13 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
def test_reallocate_deallocated_v4_ip_passed_subnets(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
next_auto_assign_ip=0,
ip_policy=None)
subnet6 = dict(id=1, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=self.v6_fip.value + 1,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
address = models.IPAddress()
address["address"] = self.v46_val
@ -454,7 +453,7 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
subnet6 = dict(id=1, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=self.v6_fip.value + 1,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
address = models.IPAddress()
address["address"] = self.v46_val
address["version"] = 4
@ -493,7 +492,7 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
def test_reallocate_deallocated_v6_ip(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=1, network=dict(ip_policy=None),
next_auto_assign_ip=1,
ip_policy=None)
address = models.IPAddress()
address["address"] = netaddr.IPAddress(4).ipv6()
@ -514,7 +513,7 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
subnet6 = dict(id=1, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=0,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
address = models.IPAddress()
address["address"] = self.v46_val
@ -543,8 +542,7 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
ip_version=6,
ip_policy=None,
last_ip=self.v6_lip.value,
next_auto_assign_ip=0,
network=dict(ip_policy=None))
next_auto_assign_ip=0)
address = models.IPAddress()
address["address"] = self.v46_val
@ -568,7 +566,7 @@ class QuarkIpamTestBothIpAllocation(QuarkIpamBaseTest):
def test_reallocate_deallocated_v6_ip_as_string_address(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=1, network=dict(ip_policy=None),
next_auto_assign_ip=1,
ip_policy=None)
address = models.IPAddress()
address["address"] = str(self.v46_val)
@ -629,12 +627,12 @@ class QuarkIpamTestBothRequiredIpAllocation(QuarkIpamBaseTest):
def test_allocate_new_ip_address_two_empty_subnets(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=1, network=dict(ip_policy=None),
next_auto_assign_ip=1,
ip_policy=None)
subnet6 = dict(id=1, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=self.v6_fip.value + 1,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
with self._stubs(subnets=[[(subnet4, 0)], [(subnet6, 0)]],
addresses=[None, None, None, None]):
address = []
@ -648,7 +646,7 @@ class QuarkIpamTestBothRequiredIpAllocation(QuarkIpamBaseTest):
def test_allocate_new_ip_address_one_v4_subnet_open(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=2, network=dict(ip_policy=None),
next_auto_assign_ip=2,
ip_policy=None)
with self._stubs(subnets=[[(subnet4, 0)], []],
addresses=[None, None, None, None]):
@ -658,7 +656,7 @@ class QuarkIpamTestBothRequiredIpAllocation(QuarkIpamBaseTest):
def test_allocate_new_ip_address_one_v6_subnet_open(self):
subnet6 = dict(id=1, first_ip=self.v6_fip, last_ip=self.v6_lip,
cidr="feed::/104", ip_version=6,
next_auto_assign_ip=2, network=dict(ip_policy=None),
next_auto_assign_ip=2,
ip_policy=None)
with self._stubs(subnets=[[], [(subnet6, 0)]],
addresses=[None, None, None, None]):
@ -676,7 +674,7 @@ class QuarkIpamTestBothRequiredIpAllocation(QuarkIpamBaseTest):
subnet6 = dict(id=66, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=self.v6_fip.value + 1,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
address = models.IPAddress()
address["address"] = 4
address["version"] = 4
@ -694,7 +692,7 @@ class QuarkIpamTestBothRequiredIpAllocation(QuarkIpamBaseTest):
def test_reallocate_deallocated_v6_ip(self):
subnet4 = dict(id=1, first_ip=0, last_ip=255, cidr="0.0.0.0/24",
ip_version=4, next_auto_assign_ip=1,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
address = models.IPAddress()
address["address"] = 4
address["version"] = 6
@ -735,15 +733,16 @@ class QuarkIpamTestBothRequiredIpAllocation(QuarkIpamBaseTest):
subnet4 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=1, network=dict(ip_policy=None),
next_auto_assign_ip=1,
ip_policy=None)
subnet6 = dict(id=1, first_ip=self.v6_fip.value,
last_ip=self.v6_lip.value, cidr="feed::/104",
ip_version=6, next_auto_assign_ip=-2,
network=dict(ip_policy=None),
ip_policy=dict(exclude=[
models.IPPolicyCIDR(cidr="feed::/128"),
models.IPPolicyCIDR(cidr="feed::ff:ffff/128")]))
ip_policy=dict(
size=2,
exclude=[
models.IPPolicyCIDR(cidr="feed::/128"),
models.IPPolicyCIDR(cidr="feed::ff:ffff/128")]))
with self._stubs(subnets=[[(subnet4, 0)], [(subnet6, 0)]],
addresses=[None, None, None, None]):
@ -826,7 +825,7 @@ class QuarkIpamAllocateFromV6Subnet(QuarkIpamBaseTest):
port_id = "945af340-ed34-4fec-8c87-853a2df492b4"
subnet6 = dict(id=1, first_ip=0, last_ip=0,
cidr="feed::/104", ip_version=6,
next_auto_assign_ip=0, network=dict(ip_policy=None),
next_auto_assign_ip=0,
ip_policy=None)
mac = models.MacAddress()
@ -848,7 +847,7 @@ class QuarkIpamAllocateFromV6Subnet(QuarkIpamBaseTest):
port_id = "945af340-ed34-4fec-8c87-853a2df492b4"
subnet6 = dict(id=1, first_ip=0, last_ip=0,
cidr="feed::/104", ip_version=6,
next_auto_assign_ip=0, network=dict(ip_policy=None),
next_auto_assign_ip=0,
ip_policy=None)
mac = models.MacAddress()
@ -897,7 +896,7 @@ class QuarkIpamAllocateV6IPGeneration(QuarkIpamBaseTest):
port_id = "945af340-ed34-4fec-8c87-853a2df492b4"
subnet6 = dict(id=1, first_ip=0, last_ip=0,
cidr="feed::/104", ip_version=6,
next_auto_assign_ip=0, network=dict(ip_policy=None),
next_auto_assign_ip=0,
ip_policy=None)
ip1 = {"address": netaddr.IPAddress("fe80::").value,
@ -934,8 +933,8 @@ class QuarkNewIPAddressAllocation(QuarkIpamBaseTest):
def test_allocate_new_ip_address_in_empty_range(self):
subnet = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
ip_policy=dict(exclude=[
next_auto_assign_ip=0,
ip_policy=dict(size=1, exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/32")]))
with self._stubs(subnets=[(subnet, 0)], addresses=[None, None]):
address = []
@ -947,14 +946,15 @@ class QuarkNewIPAddressAllocation(QuarkIpamBaseTest):
def test_allocate_ip_one_full_one_open_subnet(self):
subnet1 = dict(id=1, first_ip=0, last_ip=0,
cidr="0.0.0.0/32", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
ip_policy=dict(exclude=[
next_auto_assign_ip=0,
ip_policy=dict(size=1, exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/32")]))
subnet2 = dict(id=2, first_ip=256, last_ip=512,
cidr="0.0.1.0/24", ip_version=4,
next_auto_assign_ip=256, network=dict(ip_policy=None),
ip_policy=dict(exclude=[
models.IPPolicyCIDR(cidr="0.0.1.0/32")]))
next_auto_assign_ip=256,
ip_policy=dict(
size=1,
exclude=[models.IPPolicyCIDR(cidr="0.0.1.0/32")]))
subnets = [(subnet1, 1), (subnet2, 0)]
with self._stubs(subnets=subnets, addresses=[None, None]):
address = []
@ -971,9 +971,9 @@ class QuarkNewIPAddressAllocation(QuarkIpamBaseTest):
def test_allocate_ip_no_available_subnet_fails(self):
subnet1 = dict(id=1, first_ip=0, last_ip=0, next_auto_assign_ip=0,
cidr="0.0.0.0/32", ip_version=4,
network=dict(ip_policy=None),
ip_policy=dict(exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/32")]))
ip_policy=dict(
size=1,
exclude=[models.IPPolicyCIDR(cidr="0.0.0.0/32")]))
with self._stubs(subnets=[(subnet1, 1)]):
with self.assertRaises(exceptions.IpAddressGenerationFailure):
self.ipam.allocate_ip_address(self.context, [], 0, 0, 0)
@ -981,13 +981,13 @@ class QuarkNewIPAddressAllocation(QuarkIpamBaseTest):
def test_allocate_ip_two_open_subnets_choses_first(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
ip_policy=dict(exclude=[
next_auto_assign_ip=0,
ip_policy=dict(size=1, exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/32")]))
subnet2 = dict(id=2, first_ip=256, last_ip=510,
cidr="0.0.1.0/24", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
ip_policy=dict(exclude=[
next_auto_assign_ip=0,
ip_policy=dict(size=1, exclude=[
models.IPPolicyCIDR(cidr="0.0.1.0/32")]))
subnets = [(subnet1, 1), (subnet2, 1)]
with self._stubs(subnets=subnets, addresses=[None, None]):
@ -1000,7 +1000,6 @@ class QuarkNewIPAddressAllocation(QuarkIpamBaseTest):
def test_find_requested_ip_subnet(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
network=dict(ip_policy=None),
ip_policy=None)
subnets = [(subnet1, 1)]
with self._stubs(subnets=subnets, addresses=[None, None]):
@ -1039,7 +1038,7 @@ class QuarkIPAddressAllocationTestRetries(QuarkIpamBaseTest):
def test_allocate_allocated_ip_fails_and_retries(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255, next_auto_assign_ip=1,
cidr="0.0.0.0/24", ip_version=4,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
subnets = [(subnet1, 1)]
addr_found = dict(id=1, address=2)
with self._stubs(subnets=subnets,
@ -1053,7 +1052,7 @@ class QuarkIPAddressAllocationTestRetries(QuarkIpamBaseTest):
def test_allocate_explicit_already_allocated_fails_and_retries(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255, next_auto_assign_ip=1,
cidr="0.0.0.0/24", ip_version=4,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
subnets = [(subnet1, 1), (subnet1, 1)]
addr_found = dict(id=1, address=1)
with self._stubs(subnets=subnets,
@ -1066,7 +1065,7 @@ class QuarkIPAddressAllocationTestRetries(QuarkIpamBaseTest):
def test_allocate_implicit_already_allocated_fails_and_retries(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255, next_auto_assign_ip=1,
cidr="::/64", ip_version=6,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
subnets = [(subnet1, 1), (subnet1, 1)]
addr_found = dict(id=1, address=1)
@ -1083,7 +1082,7 @@ class QuarkIPAddressAllocationTestRetries(QuarkIpamBaseTest):
def test_allocate_specific_subnet_ip_not_in_subnet_fails(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255, next_auto_assign_ip=1,
cidr="0.0.0.0/24", ip_version=4,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
subnets = [(subnet1, 1), (subnet1, 1)]
addr_found = dict(id=1, address=256)
with self._stubs(subnets=subnets,
@ -1097,7 +1096,7 @@ class QuarkIPAddressAllocationTestRetries(QuarkIpamBaseTest):
def test_allocate_specific_subnet_unusable_fails(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255, next_auto_assign_ip=1,
cidr="0.0.0.0/24", ip_version=4,
network=dict(ip_policy=None), ip_policy=None,
ip_policy=None,
do_not_use=1)
subnets = []
addr_found = dict(id=1, address=256)
@ -1112,7 +1111,7 @@ class QuarkIPAddressAllocationTestRetries(QuarkIpamBaseTest):
def test_allocate_last_ip_closes_subnet(self):
subnet1 = dict(id=1, first_ip=0, last_ip=1, next_auto_assign_ip=1,
cidr="0.0.0.0/24", ip_version=4,
network=dict(ip_policy=None), ip_policy=None)
ip_policy=None)
subnets = [(subnet1, 1)]
addr_found = dict(id=1, address=1)
with self._stubs(subnets=subnets, address=[addr_found]):
@ -1157,8 +1156,7 @@ class QuarkIPAddressAllocateDeallocated(QuarkIpamBaseTest):
def test_allocate_finds_deallocated_ip_out_of_range_deletes(self):
subnet = dict(id=1, ip_version=4, next_auto_assign_ip=2,
cidr="0.0.0.0/29", ip_policy=None,
network=dict(ip_policy=None))
cidr="0.0.0.0/29", ip_policy=None)
address = dict(id=1, address=254)
address2 = dict(id=1, address=1)
address["subnet"] = subnet
@ -1175,7 +1173,7 @@ class QuarkIPAddressAllocateDeallocated(QuarkIpamBaseTest):
def test_allocate_finds_no_deallocated_creates_new_ip(self):
subnet = dict(id=1, ip_version=4, next_auto_assign_ip=2,
cidr="0.0.0.0/24", first_ip=0, last_ip=255,
ip_policy=None, network=dict(ip_policy=None))
ip_policy=None)
address = dict(id=1, address=0)
addresses_found = [None, address, None]
with self._stubs(
@ -1210,8 +1208,7 @@ class TestQuarkIpPoliciesIpAllocation(QuarkIpamBaseTest):
subnet = dict(id=1, first_ip=first, last_ip=last,
cidr="192.168.0.0/24", ip_version=4,
next_auto_assign_ip=first,
network=dict(ip_policy=None),
ip_policy=dict(exclude=[
ip_policy=dict(size=1, exclude=[
models.IPPolicyCIDR(cidr="192.168.0.0/32")]))
with self._stubs(subnets=[(subnet, 0)], addresses=[None, None]):
address = []
@ -1222,8 +1219,8 @@ class TestQuarkIpPoliciesIpAllocation(QuarkIpamBaseTest):
def test_subnet_full_based_on_ip_policy(self):
subnet = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
ip_policy=dict(exclude=[
next_auto_assign_ip=0,
ip_policy=dict(size=256, exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/24")]))
with self._stubs(subnets=[(subnet, 0)], addresses=[None, None]):
with self.assertRaises(exceptions.IpAddressGenerationFailure):
@ -1235,8 +1232,8 @@ class TestQuarkIpPoliciesIpAllocation(QuarkIpamBaseTest):
cfg.CONF.set_override('ip_address_retry_max', 3, 'QUARK')
subnet = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
ip_policy=dict(exclude=[
next_auto_assign_ip=0,
ip_policy=dict(size=2, exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/31")]))
with self._stubs(subnets=[(subnet, 0)], addresses=[None, None]):
address = []
@ -1247,12 +1244,10 @@ class TestQuarkIpPoliciesIpAllocation(QuarkIpamBaseTest):
cfg.CONF.set_override('ip_address_retry_max', old_override, 'QUARK')
def test_ip_policy_on_both_subnet_preferred(self):
net = dict(ip_policy=dict(exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/31")]))
subnet = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=0, network=net,
ip_policy=dict(exclude=[
next_auto_assign_ip=0,
ip_policy=dict(size=1, exclude=[
models.IPPolicyCIDR(cidr="0.0.0.0/32")]))
with self._stubs(subnets=[(subnet, 0)], addresses=[None, None]):
address = []
@ -1264,7 +1259,6 @@ class TestQuarkIpPoliciesIpAllocation(QuarkIpamBaseTest):
def test_ip_policy_allows_specified_ip(self):
subnet1 = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
network=dict(ip_policy=None),
ip_policy=dict(exclude=[
models.IPPolicyCIDR(cidr="0.0.0.240/32")]))
subnets = [(subnet1, 1)]
@ -1299,7 +1293,7 @@ class QuarkIPAddressAllocationNotifications(QuarkIpamBaseTest):
def test_allocation_notification(self):
subnet = dict(id=1, first_ip=0, last_ip=255,
cidr="0.0.0.0/24", ip_version=4,
next_auto_assign_ip=0, network=dict(ip_policy=None),
next_auto_assign_ip=0,
ip_policy=None)
address = dict(address=0, created_at="123", subnet_id=1,
address_readable="0.0.0.0", used_by_tenant_id=1)

View File

@ -13,6 +13,7 @@ from sqlalchemy.sql import column
from sqlalchemy.sql import select
from sqlalchemy.sql import table
from quark.db.custom_types import INET
import quark.db.migration
from quark.tests import test_base
@ -621,3 +622,79 @@ class Test552b213c2b8c(BaseMigrationTest):
alembic_command.upgrade(self.config, '552b213c2b8c')
with self.assertRaises(NotImplementedError):
alembic_command.downgrade(self.config, '45a07fac3d38')
class Test28e55acaf366(BaseMigrationTest):
def setUp(self):
super(Test28e55acaf366, self).setUp()
alembic_command.upgrade(self.config, '3d22de205729')
self.ip_policy = table('quark_ip_policy',
column('id', sa.String(length=36)),
column('size', INET()))
self.ip_policy_cidrs = table(
'quark_ip_policy_cidrs',
column('id', sa.String(length=36)),
column('ip_policy_id', sa.String(length=36)),
column('cidr', sa.String(length=64)))
def test_upgrade_none(self):
alembic_command.upgrade(self.config, '28e55acaf366')
results = self.connection.execute(select([
self.ip_policy])).fetchall()
self.assertEqual(len(results), 0)
results = self.connection.execute(select([
self.ip_policy_cidrs])).fetchall()
self.assertEqual(len(results), 0)
def test_upgrade_v4(self):
self.connection.execute(
self.ip_policy.insert(), dict(id="1", size=None))
self.connection.execute(
self.ip_policy_cidrs.insert(),
dict(id="2", ip_policy_id="1", cidr="192.168.10.13/32"),
dict(id="3", ip_policy_id="1", cidr="192.168.10.16/31"))
alembic_command.upgrade(self.config, '28e55acaf366')
results = self.connection.execute(select([
self.ip_policy])).fetchall()
self.assertEqual(len(results), 1)
self.assertEqual(results[0]["id"], "1")
self.assertEqual(results[0]["size"], 3)
def test_upgrade_v6(self):
self.connection.execute(
self.ip_policy.insert(), dict(id="1", size=None))
self.connection.execute(
self.ip_policy_cidrs.insert(),
dict(id="2", ip_policy_id="1", cidr="fd00::/64"))
alembic_command.upgrade(self.config, '28e55acaf366')
results = self.connection.execute(select([
self.ip_policy])).fetchall()
self.assertEqual(len(results), 1)
self.assertEqual(results[0]["id"], "1")
self.assertEqual(results[0]["size"], 2 ** 64)
def test_upgrade_bulk(self):
self.connection.execute(
self.ip_policy.insert(),
dict(id="1", size=None),
dict(id="2", size=None))
self.connection.execute(
self.ip_policy_cidrs.insert(),
dict(id="2", ip_policy_id="1", cidr="192.168.10.13/32"),
dict(id="3", ip_policy_id="1", cidr="192.168.10.16/31"),
dict(id="4", ip_policy_id="2", cidr="fd00::/64"))
alembic_command.upgrade(self.config, '28e55acaf366')
results = self.connection.execute(select([
self.ip_policy])).fetchall()
self.assertEqual(len(results), 2)
for result in results:
self.assertIn(result["id"], ("1", "2"))
if result["id"] == "1":
self.assertEqual(result["size"], 3)
elif result["id"] == "2":
self.assertEqual(result["size"], 2 ** 64)
def test_downgrade(self):
alembic_command.upgrade(self.config, '28e55acaf366')
with self.assertRaises(NotImplementedError):
alembic_command.downgrade(self.config, '3d22de205729')