AllowedIps Route with create and index
This commit is contained in:
parent
9c23eca47f
commit
e70a3fe458
@ -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()
|
||||
|
@ -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()],
|
||||
|
@ -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,
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user