Implemented DELETE and GET /mac_address_ranges/<uuid>
* Added exceptions.MacAddressRangeNotFound, exceptions.MacAddressRangeInUse * Implemented tests for plugin.get_mac_address_range * Implemented tests for plugin.delete_mac_address_range
This commit is contained in:
@@ -61,10 +61,12 @@ class MacAddressRangesController(wsgi.Controller):
|
||||
|
||||
def show(self, request, id):
|
||||
context = request.context
|
||||
tenant_id = id
|
||||
if not tenant_id:
|
||||
raise webob.exc.HTTPBadRequest('invalid tenant')
|
||||
return self._plugin.get_mac_address_range(context, id)
|
||||
return {"mac_address_range":
|
||||
self._plugin.get_mac_address_range(context, id)}
|
||||
|
||||
def delete(self, request, id, **kwargs):
|
||||
context = request.context
|
||||
return self._plugin.delete_mac_address_range(context, id)
|
||||
|
||||
|
||||
class Mac_address_ranges(object):
|
||||
|
||||
@@ -252,6 +252,10 @@ def mac_address_range_create(context, **range_dict):
|
||||
return new_range
|
||||
|
||||
|
||||
def mac_address_range_delete(context, mac_address_range):
|
||||
context.session.delete(mac_address_range)
|
||||
|
||||
|
||||
def mac_address_update(context, mac, **kwargs):
|
||||
mac.update(kwargs)
|
||||
context.session.add(mac)
|
||||
|
||||
@@ -306,7 +306,8 @@ class MacAddress(BASEV2, models.HasTenant):
|
||||
__tablename__ = "quark_mac_addresses"
|
||||
address = sa.Column(sa.BigInteger(), primary_key=True)
|
||||
mac_address_range_id = sa.Column(
|
||||
sa.String(36), sa.ForeignKey("quark_mac_address_ranges.id"),
|
||||
sa.String(36),
|
||||
sa.ForeignKey("quark_mac_address_ranges.id", ondelete="CASCADE"),
|
||||
nullable=False)
|
||||
deallocated = sa.Column(sa.Boolean())
|
||||
deallocated_at = sa.Column(sa.DateTime())
|
||||
@@ -319,6 +320,11 @@ class MacAddressRange(BASEV2, models.HasId):
|
||||
first_address = sa.Column(sa.BigInteger(), nullable=False)
|
||||
last_address = sa.Column(sa.BigInteger(), nullable=False)
|
||||
next_auto_assign_mac = sa.Column(sa.BigInteger(), nullable=False)
|
||||
allocated_macs = orm.relationship(MacAddress,
|
||||
primaryjoin='and_(MacAddressRange.id=='
|
||||
'MacAddress.mac_address_range_id, '
|
||||
'MacAddress.deallocated!=1)',
|
||||
backref="mac_address_range")
|
||||
|
||||
|
||||
class Network(BASEV2, models.HasTenant, models.HasId):
|
||||
|
||||
@@ -5,6 +5,14 @@ class InvalidMacAddressRange(exceptions.QuantumException):
|
||||
message = _("Invalid MAC address range %(cidr)s.")
|
||||
|
||||
|
||||
class MacAddressRangeNotFound(exceptions.NotFound):
|
||||
message = _("MAC address range %(mac_address_range_id) not found.")
|
||||
|
||||
|
||||
class MacAddressRangeInUse(exceptions.InUse):
|
||||
message = _("MAC address range %(mac_address_range_id) in use.")
|
||||
|
||||
|
||||
class RouteNotFound(exceptions.NotFound):
|
||||
message = _("Route %(route_id)s not found.")
|
||||
|
||||
|
||||
@@ -893,6 +893,27 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2,
|
||||
|
||||
return self._make_port_dict(port)
|
||||
|
||||
def get_mac_address_range(self, context, id, fields=None):
|
||||
"""Retrieve a mac_address_range.
|
||||
|
||||
: param context: quantum api request context
|
||||
: param id: UUID representing the network to fetch.
|
||||
: param fields: a list of strings that are valid keys in a
|
||||
network dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
|
||||
object in quantum/api/v2/attributes.py. Only these fields
|
||||
will be returned.
|
||||
"""
|
||||
LOG.info("get_mac_address_range %s for tenant %s fields %s" %
|
||||
(id, context.tenant_id, fields))
|
||||
|
||||
mac_address_range = db_api.mac_address_range_find(
|
||||
context, id=id, scope=db_api.ONE)
|
||||
|
||||
if not mac_address_range:
|
||||
raise quark_exceptions.MacAddressRangeNotFound(
|
||||
mac_address_range_id=id)
|
||||
return self._make_mac_range_dict(mac_address_range)
|
||||
|
||||
def get_mac_address_ranges(self, context):
|
||||
LOG.info("get_mac_address_ranges for tenant %s" % context.tenant_id)
|
||||
ranges = db_api.mac_address_range_find(context)
|
||||
@@ -930,6 +951,26 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2,
|
||||
prefix_int = int(prefix, base=16)
|
||||
return cidr, prefix_int, prefix_int + mask_size
|
||||
|
||||
def _delete_mac_address_range(self, context, mac_address_range):
|
||||
if mac_address_range.allocated_macs:
|
||||
raise quark_exceptions.MacAddressRangeInUse(
|
||||
mac_address_range_id=mac_address_range["id"])
|
||||
db_api.mac_address_range_delete(context, mac_address_range)
|
||||
|
||||
def delete_mac_address_range(self, context, id):
|
||||
"""Delete a mac_address_range.
|
||||
|
||||
: param context: quantum api request context
|
||||
: param id: UUID representing the mac_address_range to delete.
|
||||
"""
|
||||
LOG.info("delete_mac_address_range %s for tenant %s" %
|
||||
(id, context.tenant_id))
|
||||
mar = db_api.mac_address_range_find(context, id=id, scope=db_api.ONE)
|
||||
if not mar:
|
||||
raise quark_exceptions.MacAddressRangeNotFound(
|
||||
mac_address_range_id=id)
|
||||
self._delete_mac_address_range(context, mar)
|
||||
|
||||
def get_route(self, context, id):
|
||||
LOG.info("get_route %s for tenant %s" % (id, context.tenant_id))
|
||||
route = db_api.route_find(context, id=id)
|
||||
|
||||
@@ -1466,16 +1466,28 @@ class TestQuarkGetMacAddressRanges(TestQuarkPlugin):
|
||||
def _stubs(self, mac_range):
|
||||
db_mod = "quark.db.api"
|
||||
with mock.patch("%s.mac_address_range_find" % db_mod) as mar_find:
|
||||
mar_find.return_value = [mac_range]
|
||||
mar_find.return_value = mac_range
|
||||
yield
|
||||
|
||||
def test_find_mac_ranges(self):
|
||||
mar = dict(id=1, cidr="AA:BB:CC/24")
|
||||
with self._stubs(mar):
|
||||
with self._stubs([mar]):
|
||||
res = self.plugin.get_mac_address_ranges(self.context)
|
||||
self.assertEqual(res[0]["id"], mar["id"])
|
||||
self.assertEqual(res[0]["cidr"], mar["cidr"])
|
||||
|
||||
def test_find_mac_range(self):
|
||||
mar = dict(id=1, cidr="AA:BB:CC/24")
|
||||
with self._stubs(mar):
|
||||
res = self.plugin.get_mac_address_range(self.context, 1)
|
||||
self.assertEqual(res["id"], mar["id"])
|
||||
self.assertEqual(res["cidr"], mar["cidr"])
|
||||
|
||||
def test_find_mac_range_fail(self):
|
||||
with self._stubs(None):
|
||||
with self.assertRaises(quark_exceptions.MacAddressRangeNotFound):
|
||||
self.plugin.get_mac_address_range(self.context, 1)
|
||||
|
||||
|
||||
class TestQuarkCreateMacAddressRanges(TestQuarkPlugin):
|
||||
@contextlib.contextmanager
|
||||
@@ -1537,6 +1549,40 @@ class TestQuarkCreateMacAddressRanges(TestQuarkPlugin):
|
||||
cidr, first, last = self.plugin._to_mac_range("F0-0-BAR")
|
||||
|
||||
|
||||
class TestQuarkDeleteMacAddressRanges(TestQuarkPlugin):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, mac_range):
|
||||
db_mod = "quark.db.api"
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.mac_address_range_find" % db_mod),
|
||||
mock.patch("%s.mac_address_range_delete" % db_mod),
|
||||
) as (mar_find, mar_delete):
|
||||
mar_find.return_value = mac_range
|
||||
yield mar_delete
|
||||
|
||||
def test_mac_address_range_delete_not_found(self):
|
||||
with self._stubs(None):
|
||||
with self.assertRaises(quark_exceptions.MacAddressRangeNotFound):
|
||||
self.plugin.delete_mac_address_range(self.context, 1)
|
||||
|
||||
def test_mac_address_range_delete_in_use(self):
|
||||
mar = mock.MagicMock()
|
||||
mar.id = 1
|
||||
mar.allocated_macs = 1
|
||||
with self._stubs(mar):
|
||||
with self.assertRaises(quark_exceptions.MacAddressRangeInUse):
|
||||
self.plugin.delete_mac_address_range(self.context, 1)
|
||||
|
||||
def test_mac_address_range_delete_success(self):
|
||||
mar = mock.MagicMock()
|
||||
mar.id = 1
|
||||
mar.allocated_macs = 0
|
||||
with self._stubs(mar) as mar_delete:
|
||||
resp = self.plugin.delete_mac_address_range(self.context, 1)
|
||||
self.assertIsNone(resp)
|
||||
mar_delete.assert_called_once_with(self.context, mar)
|
||||
|
||||
|
||||
class TestQuarkGetRoutes(TestQuarkPlugin):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, routes):
|
||||
|
||||
Reference in New Issue
Block a user