Merge branch 'master' of github.com:jkoelker/quark

This commit is contained in:
Matt Dietz 2013-03-01 23:34:26 +00:00
commit f16f1f91a0
6 changed files with 96 additions and 8 deletions

21
quark/db/custom_types.py Normal file
View File

@ -0,0 +1,21 @@
import sqlalchemy as sa
from sqlalchemy import types
from sqlalchemy.dialects import sqlite
class INET(types.TypeDecorator):
impl = types.LargeBinary
def load_dialect_impl(self, dialect):
if dialect.name == 'sqlite':
return dialect.type_descriptor(sqlite.CHAR)
return dialect.type_descriptor(self.impl)
class MACAddress(types.TypeDecorator):
impl = types.BigInteger
def load_dialect_impl(self, dialect):
if dialect.name == 'sqlite':
return dialect.type_descriptor(sqlite.CHAR)
return dialect.type_descriptor(self.impl)

View File

@ -26,6 +26,8 @@ from quantum.db.models_v2 import HasTenant, HasId
from quantum.openstack.common import timeutils from quantum.openstack.common import timeutils
from quantum.openstack.common import log as logging from quantum.openstack.common import log as logging
from quark.db import custom_types
LOG = logging.getLogger("quantum.quark.db.models") LOG = logging.getLogger("quantum.quark.db.models")
@ -109,7 +111,7 @@ class IPAddress(BASEV2, HasId, HasTenant):
address_readable = sa.Column(sa.String(128), nullable=False) address_readable = sa.Column(sa.String(128), nullable=False)
address = sa.Column(sa.LargeBinary(16), nullable=False) address = sa.Column(custom_types.INET(), nullable=False)
subnet_id = sa.Column(sa.String(36), subnet_id = sa.Column(sa.String(36),
sa.ForeignKey("quark_subnets.id", sa.ForeignKey("quark_subnets.id",
@ -191,11 +193,15 @@ class Subnet(BASEV2, HasId, HasTenant, IsHazTags):
def cidr(cls): def cidr(cls):
return Subnet._cidr return Subnet._cidr
first_ip = sa.Column(sa.LargeBinary()) first_ip = sa.Column(custom_types.INET())
last_ip = sa.Column(sa.LargeBinary()) last_ip = sa.Column(custom_types.INET())
ip_version = sa.Column(sa.Integer()) ip_version = sa.Column(sa.Integer())
allocated_ips = orm.relationship(IPAddress, backref="subnet") allocated_ips = orm.relationship(IPAddress,
primaryjoin=
'and_(Subnet.id==IPAddress.subnet_id, '
'IPAddress._deallocated!=1)',
backref="subnet")
routes = orm.relationship(Route, backref='subnet', cascade='delete') routes = orm.relationship(Route, backref='subnet', cascade='delete')

View File

@ -65,7 +65,7 @@ class QuarkIpam(object):
return deallocated_mac return deallocated_mac
ranges = session.query(models.MacAddressRange, ranges = session.query(models.MacAddressRange,
sql_func.count(models.MacAddress). sql_func.count(models.MacAddress.address).
label("count")).\ label("count")).\
outerjoin(models.MacAddress).\ outerjoin(models.MacAddress).\
group_by(models.MacAddressRange).\ group_by(models.MacAddressRange).\
@ -127,6 +127,7 @@ class QuarkIpam(object):
address["version"] = subnet["ip_version"] address["version"] = subnet["ip_version"]
address["network_id"] = net_id address["network_id"] = net_id
address["tenant_id"] = subnet["tenant_id"] address["tenant_id"] = subnet["tenant_id"]
address["_deallocated"] = 0
if address: if address:
address["port_id"] = port_id address["port_id"] = port_id

View File

@ -49,7 +49,8 @@ quark_opts = [
] ]
CONF.register_opts(quark_opts, "QUARK") CONF.register_opts(quark_opts, "QUARK")
CONF.set_override('api_extensions_path', ":".join(extensions.__path__)) if 'api_extensions_path' in CONF:
CONF.set_override('api_extensions_path', ":".join(extensions.__path__))
class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2): class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2):
@ -343,7 +344,7 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2):
subnets = [] subnets = []
if network["network"].get("subnets"): if network["network"].get("subnets"):
subnets = network["network"].pop("subnets") subnets = network["network"].pop("subnets")
new_net = models.Network(id=net_uuid) new_net = models.Network(id=net_uuid, tenant_id=context.tenant_id)
new_net.update(network["network"]) new_net.update(network["network"])
for sub in subnets: for sub in subnets:
@ -520,6 +521,7 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2):
new_port["backend_key"] = backend_port["uuid"] new_port["backend_key"] = backend_port["uuid"]
new_port["addresses"] = addresses new_port["addresses"] = addresses
new_port["mac_address"] = mac["address"] new_port["mac_address"] = mac["address"]
new_port["tenant_id"] = context.tenant_id
session.add(new_port) session.add(new_port)
session.add(mac) session.add(mac)
@ -665,8 +667,9 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2):
raise exceptions.NetworkNotFound(net_id=id) raise exceptions.NetworkNotFound(net_id=id)
backend_key = port["backend_key"] backend_key = port["backend_key"]
mac_address = netaddr.EUI(port["mac_address"]).value
self.ipam_driver.deallocate_mac_address(session, self.ipam_driver.deallocate_mac_address(session,
port["mac_address"]) mac_address,)
self.ipam_driver.deallocate_ip_address( self.ipam_driver.deallocate_ip_address(
session, id, ipam_reuse_after=self.ipam_reuse_after) session, id, ipam_reuse_after=self.ipam_reuse_after)
session.delete(port) session.delete(port)

6
quark/tests/test_base.py Normal file
View File

@ -0,0 +1,6 @@
import unittest2
class TestBase(unittest2.TestCase):
'''Class to decide which unit test class to inherit from uniformly.'''
pass

View File

@ -0,0 +1,51 @@
from collections import namedtuple
from sqlalchemy import create_engine
from quantum.db import api as db_api
from quark.db import models
import quark.plugin
import test_base
class TestSubnets(test_base.TestBase):
def setUp(self):
db_api._ENGINE = create_engine('sqlite://')
db_api.register_models()
self.session = db_api.get_session()
self.plugin = quark.plugin.Plugin()
def test_allocated_ips_only(self):
MockContext = namedtuple('MockContext', ['tenant_id', 'session'])
context = MockContext('0', self.session)
# 1. Create network
network = {'network': {'name': 'test'}}
response = self.plugin.create_network(context, network)
network_id = response['id']
# 2. Create subnet
subnet = {'subnet': {'cidr': '192.168.10.1/24',
'network_id': network_id}}
self.plugin.create_subnet(context, subnet)
# 3. Create M.A.R.
mac_range = {'mac_address_range': {'cidr': '01:23:45/24'}}
self.plugin.create_mac_address_range(context, mac_range)
# 4. Create port
port = {'port': {'network_id': network_id,
'device_id': ''}}
response = self.plugin.create_port(context, port)
q = self.session.query(models.Subnet).outerjoin(models.IPAddress)
self.assertEqual(len(q.first().allocated_ips),
1)
# 5. Delete port.
self.plugin.delete_port(context, response['id'])
q = self.session.query(models.Subnet).outerjoin(models.IPAddress)
self.assertEqual(len(q.first().allocated_ips),
0)