From 411282ce01ffe74b76462e8ae72c77f23f0939cb Mon Sep 17 00:00:00 2001 From: Vinkesh Banka Date: Tue, 25 Oct 2011 12:09:41 +0530 Subject: [PATCH] Vinkesh | Added show action on interface to return the interface configurations like mac address and ip addresses --- melange/db/sqlalchemy/api.py | 2 +- melange/ipam/models.py | 12 ++++++++---- melange/ipam/service.py | 12 +++++++++++- melange/ipam/views.py | 13 +++++++++++++ melange/tests/unit/test_ipam_models.py | 10 ++++++++++ melange/tests/unit/test_ipam_service.py | 20 ++++++++++++++++++- melange/tests/unit/test_ipam_views.py | 26 +++++++++++++++++++++++++ 7 files changed, 88 insertions(+), 7 deletions(-) diff --git a/melange/db/sqlalchemy/api.py b/melange/db/sqlalchemy/api.py index d3c9ce04..c4ed0ec4 100644 --- a/melange/db/sqlalchemy/api.py +++ b/melange/db/sqlalchemy/api.py @@ -241,6 +241,6 @@ def _query_by(cls, **conditions): def _limits(query_func, model, conditions, limit, marker, marker_column=None): query = query_func(model, **conditions) marker_column = marker_column or model.id - if marker is not None: + if marker: query = query.filter(marker_column > marker) return query.order_by(marker_column).limit(limit) diff --git a/melange/ipam/models.py b/melange/ipam/models.py index 31861271..25f01a62 100644 --- a/melange/ipam/models.py +++ b/melange/ipam/models.py @@ -158,7 +158,7 @@ class ModelBase(object): def _validate_existence_of(self, attribute, model_class, **conditions): model_id = self[attribute] conditions['id'] = model_id - if model_id is not None and model_class.get_by(**conditions) is None: + if model_id and model_class.get_by(**conditions) is None: conditions_str = ", ".join(["{0} = {1}".format(key, repr(value)) for key, value in conditions.iteritems()]) model_class_name = model_class.__name__ @@ -363,7 +363,7 @@ class IpBlock(ModelBase): self._address_is_allocatable(policy, address), IpAddressIterator(generator)) - if address is not None: + if address: return address self.update(is_full=True) @@ -727,7 +727,7 @@ class Interface(ModelBase): interface = Interface.get_by(virtual_interface_id=virtual_interface_id, device_id=device_id, tenant_id=tenant_id) - if interface is not None: + if interface: return interface return cls.create_and_configure(virtual_interface_id, @@ -769,6 +769,10 @@ class Interface(ModelBase): def mac_address(self): return MacAddress.get_by(interface_id=self.id) + @property + def ip_addresses(self): + return IpAddress.find_all(interface_id=self.id).all() + @property def mac_address_eui_format(self): if self.mac_address: @@ -911,7 +915,7 @@ class Network(ModelBase): def _allocate_specific_ip(self, address, **kwargs): ip_block = utils.find(lambda ip_block: ip_block.contains(address), self.ip_blocks) - if ip_block is not None: + if ip_block: try: return ip_block.allocate_ip(address=address, **kwargs) except DuplicateAddressError: diff --git a/melange/ipam/service.py b/melange/ipam/service.py index 7cc217ff..0cad06c2 100644 --- a/melange/ipam/service.py +++ b/melange/ipam/service.py @@ -160,7 +160,7 @@ class AllocatedIpAddressesController(BaseController): def index(self, request, tenant_id=None): filter_conditions = utils.filter_dict(request.params, 'used_by_device') - if tenant_id is not None: + if tenant_id: filter_conditions['used_by_tenant'] = tenant_id ips = models.IpAddress.find_all_allocated_ips(**filter_conditions) return self._paginated_response('ip_addresses', ips, request) @@ -401,6 +401,12 @@ class InterfacesController(BaseController): interface = models.Interface.find_by(virtual_interface_id=id) interface.delete() + def show(self, request, id, tenant_id=None): + interface = models.Interface.find_by(virtual_interface_id=id, + tenant_id=tenant_id) + view_data = views.InterfaceConfigurationView(interface).data() + return dict(interface=view_data) + class API(wsgi.Router): @@ -443,6 +449,10 @@ class API(wsgi.Router): interface_res = InterfacesController().create_resource() path = ("/ipam/interfaces") mapper.resource("ip_interfaces", path, controller=interface_res) + self._connect(mapper, "/ipam/tenants/{tenant_id}/interfaces/{id}", + controller=interface_res, + action="show", + conditions=dict(method=['GET'])) def _network_mapper(self, mapper): path = ("/ipam/tenants/{tenant_id}/networks" diff --git a/melange/ipam/views.py b/melange/ipam/views.py index 806581bb..8d4fd8f7 100644 --- a/melange/ipam/views.py +++ b/melange/ipam/views.py @@ -62,3 +62,16 @@ class IpConfigurationView(object): 'gateway': route.gateway, 'netmask': route.netmask, } + + +class InterfaceConfigurationView(object): + + def __init__(self, interface): + self.interface = interface + + def data(self): + data = self.interface.data() + data['mac_address'] = self.interface.mac_address_eui_format + ip_addresses = self.interface.ip_addresses + data['ip_addresses'] = IpConfigurationView(*ip_addresses).data() + return data diff --git a/melange/tests/unit/test_ipam_models.py b/melange/tests/unit/test_ipam_models.py index aeec31cf..769e627b 100644 --- a/melange/tests/unit/test_ipam_models.py +++ b/melange/tests/unit/test_ipam_models.py @@ -2018,6 +2018,16 @@ class TestInterface(tests.BaseTest): self.assertIsNone(interface.mac_address_eui_format) + def test_ip_addresses(self): + interface = factory_models.InterfaceFactory() + + ip1 = factory_models.IpAddressFactory(interface_id=interface.id) + ip2 = factory_models.IpAddressFactory(interface_id=interface.id) + noise_ip = factory_models.IpAddressFactory() + + self.assertEqual(len(interface.ip_addresses), 2) + self.assertModelsEqual(interface.ip_addresses, [ip1, ip2]) + def _allocate_ip(block, interface=None, **kwargs): if interface is None: diff --git a/melange/tests/unit/test_ipam_service.py b/melange/tests/unit/test_ipam_service.py index bd4bcb16..19e829b9 100644 --- a/melange/tests/unit/test_ipam_service.py +++ b/melange/tests/unit/test_ipam_service.py @@ -17,7 +17,6 @@ import string import unittest -import mox import netaddr import routes import webob.exc @@ -2175,6 +2174,25 @@ class TestInterfacesController(BaseTestController): self.assertTrue(models.IpAddress.get(ip2.id).marked_for_deallocation) self.assertIsNone(models.MacAddress.get(mac.id)) + def test_show_returns_allocated_ips(self): + iface = factory_models.InterfaceFactory(tenant_id="tnt_id", + virtual_interface_id="vif_id") + mac = models.MacAddress.create(address="ab:bc:cd:12:23:34", + interface_id=iface.id) + ip1 = factory_models.IpAddressFactory(interface_id=iface.id) + ip2 = factory_models.IpAddressFactory(interface_id=iface.id) + noise_ip = factory_models.IpAddressFactory() + + response = self.app.get("/ipam/tenants/tnt_id/interfaces/vif_id") + + self.assertEqual(response.status_int, 200) + iface_data = response.json["interface"] + self.assertEqual(iface_data['id'], iface.virtual_interface_id) + self.assertEqual(iface_data['mac_address'], mac.eui_format) + self.assertEqual(len(iface_data['ip_addresses']), 2) + self.assertEqual(iface_data['ip_addresses'], + views.IpConfigurationView(*iface.ip_addresses).data()) + def _allocate_ips(*args): interface = factory_models.InterfaceFactory() diff --git a/melange/tests/unit/test_ipam_views.py b/melange/tests/unit/test_ipam_views.py index be5b5d1b..a889deb8 100644 --- a/melange/tests/unit/test_ipam_views.py +++ b/melange/tests/unit/test_ipam_views.py @@ -16,6 +16,7 @@ # under the License. from melange import tests +from melange.ipam import models from melange.ipam import views from melange.tests.factories import models as factory_models @@ -70,3 +71,28 @@ def _route_data(route): 'gateway': route.gateway, 'netmask': route.netmask, } + + +class TestInterfaceConfigurationView(tests.BaseTest): + + def test_data_returns_mac_address(self): + interface = factory_models.InterfaceFactory() + mac = models.MacAddress.create(interface_id=interface.id, + address="ab-bc-cd-12-23-34") + + data = views.InterfaceConfigurationView(interface).data() + + self.assertEqual(data['mac_address'], mac.eui_format) + self.assertEqual(data['id'], interface.virtual_interface_id) + + def test_data_returns_ip_address_configuration_information(self): + interface = factory_models.InterfaceFactory() + + ip1 = factory_models.IpAddressFactory(interface_id=interface.id) + ip2 = factory_models.IpAddressFactory(interface_id=interface.id) + + data = views.InterfaceConfigurationView(interface).data() + + self.assertEqual(len(data['ip_addresses']), 2) + self.assertEqual(data['ip_addresses'], + views.IpConfigurationView(ip1, ip2).data())