AllowedIps Route with create and index

This commit is contained in:
Rajaram Mallya 2011-11-16 12:47:11 +05:30
parent 9c23eca47f
commit e70a3fe458
6 changed files with 134 additions and 37 deletions

View File

@ -218,7 +218,7 @@ def find_allowed_ips(ip_address_model,
return query
def remove_allowd_ip(**conditions):
def remove_allowed_ip(**conditions):
_query_by(mappers.AllowedIp).\
filter_by(**conditions).\
delete()

View File

@ -266,9 +266,9 @@ class IpBlock(ModelBase):
'netmask']
@classmethod
def find_allocated_ip(cls, ip_block_id, address, tenant_id):
def find_allocated_ip(cls, ip_block_id, tenant_id, **conditions):
block = IpBlock.find_by(id=ip_block_id, tenant_id=tenant_id)
allocated_ip = block.find_ip(address=address)
allocated_ip = block.find_ip(**conditions)
if allocated_ip.locked():
raise AddressLockedError()
return allocated_ip
@ -406,8 +406,8 @@ class IpBlock(ModelBase):
other_network = netaddr.IPNetwork(other_block.cidr)
return network in other_network or other_network in network
def find_ip(self, address):
return IpAddress.find_by(ip_block_id=self.id, address=address)
def find_ip(self, **kwargs):
return IpAddress.find_by(ip_block_id=self.id, **kwargs)
def deallocate_ip(self, address):
ip_address = IpAddress.find_by(ip_block_id=self.id, address=address)
@ -822,7 +822,7 @@ class Interface(ModelBase):
db_api.save_allowed_ip(self.id, ip.id)
def disallow_ip(self, ip):
db_api.remove_allowd_ip(interface_id=self.id, ip_address_id=ip.id)
db_api.remove_allowed_ip(interface_id=self.id, ip_address_id=ip.id)
def ips_allowed(self):
explicitly_allowed = Query(IpAddress,
@ -972,6 +972,17 @@ class Network(ModelBase):
for ip in ips:
ip.deallocate()
def find_allocated_ip(self, **conditions):
for ip_block in self.ip_blocks:
try:
return IpAddress.find_by(ip_block_id=ip_block.id, **conditions)
except ModelNotFoundError:
pass
raise ModelNotFoundError(_("IpAddress with %(conditions)s for "
"network %(network)s not found")
% (dict(conditions=conditions,
network=self.id)))
def _block_partitions(self):
return [[block for block in self.ip_blocks
if not block.is_ipv6()],

View File

@ -131,7 +131,7 @@ class IpAddressController(BaseController):
def show(self, request, address, ip_block_id, tenant_id):
ip_block = self._find_block(id=ip_block_id, tenant_id=tenant_id)
return dict(ip_address=ip_block.find_ip(address).data())
return dict(ip_address=ip_block.find_ip(address=address).data())
def delete(self, request, address, ip_block_id, tenant_id):
ip_block = self._find_block(id=ip_block_id, tenant_id=tenant_id)
@ -152,7 +152,7 @@ class IpAddressController(BaseController):
def restore(self, request, ip_block_id, address, tenant_id, body=None):
ip_block = self._find_block(id=ip_block_id, tenant_id=tenant_id)
ip_address = ip_block.find_ip(address)
ip_address = ip_block.find_ip(address=address)
ip_address.restore()
@ -212,18 +212,18 @@ class InsideGlobalsController(BaseController):
def create(self, request, ip_block_id, address, tenant_id, body=None):
local_ip = models.IpBlock.find_allocated_ip(ip_block_id,
address,
tenant_id)
tenant_id,
address=address)
addresses = body['ip_addresses']
global_ips = [models.IpBlock.find_allocated_ip(ip["ip_block_id"],
ip["ip_address"],
tenant_id)
tenant_id,
address=ip["ip_address"])
for ip in addresses]
local_ip.add_inside_globals(global_ips)
def index(self, request, ip_block_id, tenant_id, address):
ip_block = models.IpBlock.find_by(id=ip_block_id, tenant_id=tenant_id)
ip = ip_block.find_ip(address)
ip = ip_block.find_ip(address=address)
global_ips, marker = ip.inside_globals().paginated_collection(
**self._extract_limits(request.params))
return dict(ip_addresses=[ip.data() for ip in global_ips])
@ -231,7 +231,7 @@ class InsideGlobalsController(BaseController):
def delete(self, request, ip_block_id, address, tenant_id,
inside_globals_address=None):
ip_block = models.IpBlock.find_by(id=ip_block_id, tenant_id=tenant_id)
local_ip = ip_block.find_ip(address)
local_ip = ip_block.find_ip(address=address)
local_ip.remove_inside_globals(inside_globals_address)
@ -239,20 +239,22 @@ class InsideLocalsController(BaseController):
def create(self, request, ip_block_id, address, tenant_id, body=None):
global_ip = models.IpBlock.find_allocated_ip(ip_block_id,
address,
tenant_id)
tenant_id,
address=address,
)
addresses = body['ip_addresses']
local_ips = [models.IpBlock.find_allocated_ip(ip["ip_block_id"],
ip["ip_address"],
tenant_id)
tenant_id,
address=ip["ip_address"],
)
for ip in addresses]
global_ip.add_inside_locals(local_ips)
def index(self, request, ip_block_id, address, tenant_id):
ip_block = models.IpBlock.find_by(id=ip_block_id, tenant_id=tenant_id)
ip = ip_block.find_ip(address)
ip = ip_block.find_ip(address=address)
local_ips, marker = ip.inside_locals().paginated_collection(
**self._extract_limits(request.params))
return dict(ip_addresses=[ip.data() for ip in local_ips])
@ -260,7 +262,7 @@ class InsideLocalsController(BaseController):
def delete(self, request, ip_block_id, address, tenant_id,
inside_locals_address=None):
ip_block = models.IpBlock.find_by(id=ip_block_id, tenant_id=tenant_id)
global_ip = ip_block.find_ip(address)
global_ip = ip_block.find_ip(address=address)
global_ip.remove_inside_locals(inside_locals_address)
@ -428,6 +430,23 @@ class MacAddressRangesController(BaseController):
return wsgi.Result(dict(mac_address_range=mac_range.data()), 201)
class InterfaceAllowedIpsController(BaseController):
def index(self, request, interface_id, tenant_id):
interface = models.Interface.find_by(virtual_interface_id=interface_id,
tenant_id=tenant_id)
return dict(ip_addresses=[ip.data() for ip in interface.ips_allowed()])
def create(self, request, interface_id, tenant_id, body=None):
params = self._extract_required_params(body, 'allowed_ip')
interface = models.Interface.find_by(
virtual_interface_id=interface_id, tenant_id=tenant_id)
network = models.Network.find_by(id=params['network_id'])
ip = network.find_allocated_ip(address=params['ip_address'])
interface.allow_ip(ip)
return wsgi.Result(dict(ip_address=ip.data()), 201)
class API(wsgi.Router):
def __init__(self):
@ -469,12 +488,19 @@ class API(wsgi.Router):
def _interface_mapper(self, mapper):
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}",
interface_allowed_ips = InterfaceAllowedIpsController()
path = "/ipam/interfaces"
mapper.resource("interfaces", path, controller=interface_res)
self._connect(mapper,
"/ipam/tenants/{tenant_id}/interfaces/{id}",
controller=interface_res,
action="show",
conditions=dict(method=['GET']))
mapper.resource("allowed_ips",
"/allowed_ips",
controller=interface_allowed_ips.create_resource(),
path_prefix=("/ipam/tenants/{tenant_id}/"
"interfaces/{interface_id}"))
def _mac_address_range_mapper(self, mapper):
range_res = MacAddressRangesController().create_resource()
@ -530,8 +556,7 @@ class API(wsgi.Router):
SubnetController().create_resource(),
block_as_parent)
def _subnet_mapper(self, mapper, subnet_controller,
parent_resource):
def _subnet_mapper(self, mapper, subnet_controller, parent_resource):
path_prefix = "%s/{%s_id}" % (parent_resource["collection_path"],
parent_resource["member_name"])
with mapper.submapper(controller=subnet_controller,

View File

@ -469,7 +469,7 @@ class TestIpBlock(tests.BaseTest):
def test_find_ip(self):
block = factory_models.PrivateIpBlockFactory(cidr="10.0.0.1/8")
ip = _allocate_ip(block)
self.assertEqual(block.find_ip(ip.address).id, ip.id)
self.assertEqual(block.find_ip(address=ip.address).id, ip.id)
def test_find_ip_for_nonexistent_address(self):
block = factory_models.PrivateIpBlockFactory(cidr="10.0.0.1/8")
@ -477,7 +477,7 @@ class TestIpBlock(tests.BaseTest):
self.assertRaisesExcMessage(models.ModelNotFoundError,
"IpAddress Not Found",
block.find_ip,
"10.0.0.1")
address="10.0.0.1")
def test_policy(self):
policy = factory_models.PolicyFactory(name="Some Policy")
@ -763,9 +763,8 @@ class TestIpBlock(tests.BaseTest):
block = factory_models.PrivateIpBlockFactory()
actual_ip = _allocate_ip(block)
expected_ip = models.IpBlock.find_allocated_ip(block.id,
actual_ip.address,
block.tenant_id)
expected_ip = models.IpBlock.find_allocated_ip(
block.id, block.tenant_id, address=actual_ip.address)
self.assertEqual(expected_ip, actual_ip)
@ -778,8 +777,8 @@ class TestIpBlock(tests.BaseTest):
self.assertRaises(models.AddressLockedError,
models.IpBlock.find_allocated_ip,
block.id,
ip.address,
block.tenant_id)
block.tenant_id,
address=ip.address)
def test_find_allocated_ip_when_ip_block_not_belongs_to_tenant(self):
block = factory_models.PrivateIpBlockFactory(cidr="10.0.0.0/30")
@ -788,8 +787,8 @@ class TestIpBlock(tests.BaseTest):
self.assertRaises(models.ModelNotFoundError,
models.IpBlock.find_allocated_ip,
block.id,
ip.address,
"wrong_tenant_id_for_block")
"wrong_tenant_id",
address=ip.address)
def test_deallocate_ip(self):
interface = factory_models.InterfaceFactory()
@ -801,8 +800,8 @@ class TestIpBlock(tests.BaseTest):
self.assertRaises(models.AddressLockedError,
models.IpBlock.find_allocated_ip,
block.id,
ip.address,
block.tenant_id)
block.tenant_id,
address=ip.address)
self.assertRaises(models.DuplicateAddressError,
block.allocate_ip,
@ -1960,6 +1959,30 @@ class TestNetwork(tests.BaseTest):
self.assertModelsEqual(allocated_ips, [ip1, ip2, ip4])
def test_find_allocated_ip(self):
ip_block1 = factory_models.IpBlockFactory(network_id=1,
cidr="10.0.0.0/24")
ip_block2 = factory_models.IpBlockFactory(network_id=1,
cidr="20.0.0.0/24")
noise_block = factory_models.IpBlockFactory(network_id=1,
cidr="30.0.0.0/24")
ip1 = _allocate_ip(ip_block1)
ip2 = _allocate_ip(ip_block2)
network = models.Network.find_by(id=1)
self.assertEqual(network.find_allocated_ip(address=ip1.address), ip1)
self.assertEqual(network.find_allocated_ip(address=ip2.address), ip2)
def test_find_allocated_ip_raises_model_not_found_for_invalid_ip(self):
ip_block = factory_models.IpBlockFactory(network_id=1,
cidr="10.0.0.0/24")
network = models.Network.find_by(id=1)
self.assertRaisesExcMessage(models.ModelNotFoundError,
("IpAddress with {'address': '10.1.1.1'} "
"for network %s not found" % network.id),
network.find_allocated_ip,
address="10.1.1.1")
class TestInterface(tests.BaseTest):

View File

@ -2228,6 +2228,44 @@ class TestMacAddressRangesController(BaseTestController):
_data(mac_range))
class TestInterfaceAllowedIpsController(BaseTestController):
def test_index(self):
interface = factory_models.InterfaceFactory(
tenant_id="tnt_id", virtual_interface_id="vif_id")
noise_interface = factory_models.InterfaceFactory()
ip1 = factory_models.IpAddressFactory()
ip2 = factory_models.IpAddressFactory()
ip3 = factory_models.IpAddressFactory()
ip4 = factory_models.IpAddressFactory()
interface.allow_ip(ip1)
interface.allow_ip(ip2)
interface.allow_ip(ip3)
noise_interface.allow_ip(ip3)
noise_interface.allow_ip(ip4)
response = self.app.get(
"/ipam/tenants/tnt_id/interfaces/vif_id/allowed_ips")
self.assertItemsEqual(response.json['ip_addresses'],
_data([ip1, ip2, ip3]))
def test_create(self):
interface = factory_models.InterfaceFactory(
tenant_id="tnt_id", virtual_interface_id="vif_id")
block = factory_models.IpBlockFactory(network_id="net123")
ip = block.allocate_ip(factory_models.InterfaceFactory(
tenant_id="tnt_id"))
response = self.app.post_json(
("/ipam/tenants/tnt_id/interfaces/%s/allowed_ips"
% interface.virtual_interface_id),
{'allowed_ip': {'network_id': "net123", 'ip_address': ip.address}})
self.assertEqual(response.status_int, 201)
self.assertEqual(response.json['ip_address'], _data(ip))
def _allocate_ips(*args):
interface = factory_models.InterfaceFactory()
return [models.sort([_allocate_ip(ip_block, interface=interface)

View File

@ -86,7 +86,7 @@ function run_pep8 {
GLOBIGNORE="$ignore_scripts:$ignore_files"
srcfiles=`find bin -type f ! -name "melange.conf*"`
srcfiles+=" `find tools/*`"
srcfiles+=" setup.py bin"
srcfiles+=" setup.py bin melange"
# Just run PEP8 in current environment
#
# NOTE(sirp): W602 (deprecated 3-arg raise) is being ignored for the