interface has a list of allowed ips
This commit is contained in:
parent
0c3abeafd7
commit
e7e568d7b6
@ -38,8 +38,8 @@ default_cidr = 10.0.0.0/24
|
||||
#ipv6_generator=melange.ipv6.tenant_based_generator.TenantBasedIpV6Generator
|
||||
|
||||
#DNS info for a data_center
|
||||
dns1 = "ns1.example.com"
|
||||
dns2 = "ns2.example.com"
|
||||
dns1 = 8.8.8.8
|
||||
dns2 = 8.8.4.4
|
||||
|
||||
#Number of days before deallocated IPs are deleted
|
||||
keep_deallocated_ips_for_days = 2
|
||||
|
@ -19,6 +19,7 @@ import sqlalchemy.exc
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy import or_
|
||||
from sqlalchemy.orm import aliased
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from melange import ipam
|
||||
from melange.common import exception
|
||||
@ -71,7 +72,7 @@ def delete_all(query_func, model, **conditions):
|
||||
query_func(model, **conditions).delete()
|
||||
|
||||
|
||||
def update(model, values):
|
||||
def update(model, **values):
|
||||
for k, v in values.iteritems():
|
||||
model[k] = v
|
||||
|
||||
@ -106,7 +107,7 @@ def save_nat_relationships(nat_relationships):
|
||||
for relationship in nat_relationships:
|
||||
ip_nat = mappers.IpNat()
|
||||
relationship['id'] = utils.generate_uuid()
|
||||
update(ip_nat, relationship)
|
||||
update(ip_nat, **relationship)
|
||||
save(ip_nat)
|
||||
|
||||
|
||||
@ -203,6 +204,21 @@ def pop_allocatable_address(**conditions):
|
||||
return ip.address
|
||||
|
||||
|
||||
def save_allowed_ip(interface_id, ip_address_id):
|
||||
allowed_ip = mappers.AllowedIp()
|
||||
update(allowed_ip,
|
||||
id=utils.generate_uuid(),
|
||||
interface_id=interface_id,
|
||||
ip_address_id=ip_address_id)
|
||||
save(allowed_ip)
|
||||
|
||||
|
||||
def find_allowed_ips(**conditions):
|
||||
query = _query_by(mappers.AllowedIp, **conditions).\
|
||||
options(joinedload('ip_address'))
|
||||
return [allowed_ip.ip_address for allowed_ip in query]
|
||||
|
||||
|
||||
def configure_db(options):
|
||||
session.configure_db(options)
|
||||
|
||||
|
@ -33,6 +33,7 @@ def map(engine, models):
|
||||
mac_address_ranges_table = Table('mac_address_ranges', meta, autoload=True)
|
||||
mac_addresses_table = Table('mac_addresses', meta, autoload=True)
|
||||
interfaces_table = Table('interfaces', meta, autoload=True)
|
||||
allowed_ips_table = Table('allowed_ips', meta, autoload=True)
|
||||
|
||||
orm.mapper(models["IpBlock"], Table('ip_blocks', meta, autoload=True))
|
||||
orm.mapper(models["IpAddress"], ip_addresses_table)
|
||||
@ -60,6 +61,13 @@ def map(engine, models):
|
||||
}
|
||||
)
|
||||
|
||||
orm.mapper(AllowedIp, allowed_ips_table,
|
||||
properties={
|
||||
'interface': orm.relation(models["Interface"]),
|
||||
'ip_address': orm.relation(models["IpAddress"])
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class IpNat(object):
|
||||
"""Many to Many table for natting inside globals and locals.
|
||||
@ -75,3 +83,19 @@ class IpNat(object):
|
||||
|
||||
def __getitem__(self, key):
|
||||
return getattr(self, key)
|
||||
|
||||
|
||||
class AllowedIp(object):
|
||||
"""Many to Many table for natting inside globals and locals.
|
||||
|
||||
This resides in sqlalchemy mappers as its not a true model
|
||||
and non-relational dbs may not expose many-to-many relationships as
|
||||
another table
|
||||
|
||||
"""
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
setattr(self, key, value)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return getattr(self, key)
|
||||
|
@ -142,16 +142,24 @@ interfaces = Table('interfaces', meta,
|
||||
Column('updated_at', DateTime()),
|
||||
UniqueConstraint('virtual_interface_id'))
|
||||
|
||||
allowed_ips = Table('allowed_ips', meta,
|
||||
Column('id', String(36), primary_key=True, nullable=False),
|
||||
Column('ip_address_id', String(36), ForeignKey('ip_addresses.id'),
|
||||
nullable=False),
|
||||
Column('interface_id', String(36), ForeignKey('interfaces.id'),
|
||||
nullable=False),
|
||||
UniqueConstraint('ip_address_id', 'interface_id'))
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta.bind = migrate_engine
|
||||
create_tables([policies, ip_ranges, ip_octets, ip_blocks, ip_routes,
|
||||
mac_address_ranges, mac_addresses, interfaces, ip_addresses,
|
||||
ip_nats, allocatable_ips])
|
||||
ip_nats, allocatable_ips, allowed_ips])
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta.bind = migrate_engine
|
||||
drop_tables([allocatable_ips, ip_nats, ip_addresses, interfaces,
|
||||
mac_addresses, mac_address_ranges, ip_routes, ip_blocks,
|
||||
ip_ranges, ip_octets, policies])
|
||||
drop_tables([allowed_ips, allocatable_ips, ip_nats, ip_addresses,
|
||||
interfaces, mac_addresses, mac_address_ranges, ip_routes,
|
||||
ip_blocks, ip_ranges, ip_octets, policies])
|
||||
|
@ -338,10 +338,11 @@ class IpBlock(ModelBase):
|
||||
mac_address=interface.mac_address_eui_format,
|
||||
**kwargs)
|
||||
try:
|
||||
return IpAddress.create(address=address,
|
||||
ip_block_id=self.id,
|
||||
interface_id=interface.id)
|
||||
|
||||
ip = IpAddress.create(address=address,
|
||||
ip_block_id=self.id,
|
||||
interface_id=interface.id)
|
||||
interface.allow_ip(ip)
|
||||
return ip
|
||||
except exception.DBConstraintError as error:
|
||||
LOG.debug("IP allocation retry count :{0}".format(retries + 1))
|
||||
LOG.exception(error)
|
||||
@ -796,6 +797,12 @@ class Interface(ModelBase):
|
||||
data['id'] = self.virtual_interface_id
|
||||
return data
|
||||
|
||||
def allow_ip(self, ip):
|
||||
db_api.save_allowed_ip(self.id, ip.id)
|
||||
|
||||
def ips_allowed(self):
|
||||
return db_api.find_allowed_ips(interface_id=self.id)
|
||||
|
||||
@utils.cached_property
|
||||
def mac_address(self):
|
||||
return MacAddress.get_by(interface_id=self.id)
|
||||
|
@ -26,8 +26,8 @@ class IpBlockFactory(factory.Factory):
|
||||
FACTORY_FOR = models.IpBlock
|
||||
cidr = factory.Sequence(lambda n: "192.168.{0}.0/24".format(int(n) % 255))
|
||||
type = "private"
|
||||
dns1 = "ns1.example.com"
|
||||
dns2 = "ns2.example.com"
|
||||
dns1 = "8.8.8.8"
|
||||
dns2 = "8.8.4.4"
|
||||
tenant_id = "tenant_id"
|
||||
|
||||
|
||||
@ -40,8 +40,8 @@ class PrivateIpBlockFactory(IpBlockFactory):
|
||||
|
||||
|
||||
class IpV6IpBlockFactory(IpBlockFactory):
|
||||
cidr = factory.Sequence(lambda n: "fe::{0}00/120".format(hex(int(n) % 16)))
|
||||
type = "public"
|
||||
cidr = factory.Sequence(lambda n: "fe::{0}/120".format(hex(int(n))[2:]))
|
||||
type = "private"
|
||||
|
||||
|
||||
class IpAddressFactory(factory.Factory):
|
||||
|
@ -2124,6 +2124,29 @@ class TestInterface(tests.BaseTest):
|
||||
self.assertModelsEqual(interface.ip_addresses, [ip1, ip2])
|
||||
|
||||
|
||||
class TestAllowedIps(tests.BaseTest):
|
||||
|
||||
def test_allow_an_ip_on_an_interface(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(interface_id=interface.id)
|
||||
|
||||
interface.allow_ip(ip1)
|
||||
interface.allow_ip(ip2)
|
||||
|
||||
actual_allowed_ips = interface.ips_allowed()
|
||||
self.assertModelsEqual(actual_allowed_ips, [ip1, ip2])
|
||||
|
||||
def test_allocating_ips_allows_the_ip_on_the_interface(self):
|
||||
interface = factory_models.InterfaceFactory()
|
||||
block = factory_models.IpBlockFactory()
|
||||
|
||||
ip = block.allocate_ip(interface=interface)
|
||||
|
||||
self.assertEqual(interface.ips_allowed(), [ip])
|
||||
|
||||
|
||||
def _allocate_ip(block, interface=None, **kwargs):
|
||||
if interface is None:
|
||||
interface = factory_models.InterfaceFactory()
|
||||
|
Loading…
x
Reference in New Issue
Block a user