Merge "Extend SubnetRequestFactory to access subnet dict"
This commit is contained in:
commit
ab971d78cc
@ -31,7 +31,6 @@ from neutron.callbacks import resources
|
||||
from neutron.common import constants
|
||||
from neutron.common import exceptions as n_exc
|
||||
from neutron.common import ipv6_utils
|
||||
from neutron.common import utils
|
||||
from neutron import context as ctx
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db import ipam_non_pluggable_backend
|
||||
@ -440,32 +439,11 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
||||
external_gateway_info}}
|
||||
l3plugin.update_router(context, id, info)
|
||||
|
||||
def _make_subnet_request(self, tenant_id, subnet, subnetpool):
|
||||
cidr = subnet.get('cidr')
|
||||
subnet_id = subnet.get('id', uuidutils.generate_uuid())
|
||||
is_any_subnetpool_request = not attributes.is_attr_set(cidr)
|
||||
|
||||
if is_any_subnetpool_request:
|
||||
prefixlen = subnet['prefixlen']
|
||||
if not attributes.is_attr_set(prefixlen):
|
||||
prefixlen = int(subnetpool['default_prefixlen'])
|
||||
|
||||
return ipam.AnySubnetRequest(
|
||||
tenant_id,
|
||||
subnet_id,
|
||||
utils.ip_version_from_int(subnetpool['ip_version']),
|
||||
prefixlen)
|
||||
else:
|
||||
return ipam.SpecificSubnetRequest(tenant_id,
|
||||
subnet_id,
|
||||
cidr)
|
||||
|
||||
@oslo_db_api.wrap_db_retry(max_retries=db_api.MAX_RETRIES,
|
||||
retry_on_request=True,
|
||||
retry_on_deadlock=True)
|
||||
def _create_subnet_from_pool(self, context, subnet, subnetpool_id):
|
||||
s = subnet['subnet']
|
||||
tenant_id = self._get_tenant_id_for_create(context, s)
|
||||
self._validate_pools_with_subnetpool(s)
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
@ -474,7 +452,7 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
||||
|
||||
network = self._get_network(context, s["network_id"])
|
||||
allocator = subnet_alloc.SubnetAllocator(subnetpool, context)
|
||||
req = self._make_subnet_request(tenant_id, s, subnetpool)
|
||||
req = ipam.SubnetRequestFactory.get_request(context, s, subnetpool)
|
||||
|
||||
ipam_subnet = allocator.allocate_subnet(req)
|
||||
detail = ipam_subnet.get_details()
|
||||
@ -498,9 +476,8 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
||||
def _create_subnet_from_implicit_pool(self, context, subnet):
|
||||
s = subnet['subnet']
|
||||
self._validate_subnet(context, s)
|
||||
tenant_id = self._get_tenant_id_for_create(context, s)
|
||||
id = s.get('id', uuidutils.generate_uuid())
|
||||
detail = ipam.SpecificSubnetRequest(tenant_id,
|
||||
detail = ipam.SpecificSubnetRequest(s['tenant_id'],
|
||||
id,
|
||||
s['cidr'])
|
||||
with context.session.begin(subtransactions=True):
|
||||
@ -571,6 +548,7 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
||||
net = netaddr.IPNetwork(s['cidr'])
|
||||
subnet['subnet']['cidr'] = '%s/%s' % (net.network, net.prefixlen)
|
||||
|
||||
s['tenant_id'] = self._get_tenant_id_for_create(context, s)
|
||||
subnetpool_id = self._get_subnetpool_id(s)
|
||||
if not subnetpool_id:
|
||||
if not has_cidr:
|
||||
|
@ -14,10 +14,13 @@ import abc
|
||||
import netaddr
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
|
||||
from neutron.api.v2 import attributes
|
||||
from neutron.common import constants
|
||||
from neutron.common import ipv6_utils
|
||||
from neutron.common import utils as common_utils
|
||||
from neutron.ipam import exceptions as ipam_exc
|
||||
|
||||
|
||||
@ -243,28 +246,42 @@ class RouterGatewayAddressRequest(AddressRequest):
|
||||
"""Used to request allocating the special router gateway address."""
|
||||
|
||||
|
||||
class BaseRequestFactory(object):
|
||||
"""Factory class to create right request based on input"""
|
||||
any_request = None
|
||||
specific_request = None
|
||||
address_index = 0
|
||||
class AddressRequestFactory(object):
|
||||
"""Builds request using ip info
|
||||
|
||||
Additional parameters(port and context) are not used in default
|
||||
implementation, but planned to be used in sub-classes
|
||||
provided by specific ipam driver,
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def get_request(cls, *args, **kwargs):
|
||||
args_list = [a for a in args]
|
||||
address = args_list.pop(cls.address_index)
|
||||
if not address:
|
||||
return cls.any_request(*args_list, **kwargs)
|
||||
def get_request(cls, context, port, ip):
|
||||
if not ip:
|
||||
return AnyAddressRequest()
|
||||
else:
|
||||
return cls.specific_request(*args, **kwargs)
|
||||
return SpecificAddressRequest(ip)
|
||||
|
||||
|
||||
class AddressRequestFactory(BaseRequestFactory):
|
||||
any_request = AnyAddressRequest
|
||||
specific_request = SpecificAddressRequest
|
||||
class SubnetRequestFactory(object):
|
||||
"""Builds request using subnet info"""
|
||||
|
||||
@classmethod
|
||||
def get_request(cls, context, subnet, subnetpool):
|
||||
cidr = subnet.get('cidr')
|
||||
subnet_id = subnet.get('id', uuidutils.generate_uuid())
|
||||
is_any_subnetpool_request = not attributes.is_attr_set(cidr)
|
||||
|
||||
class SubnetRequestFactory(BaseRequestFactory):
|
||||
any_request = AnySubnetRequest
|
||||
specific_request = SpecificSubnetRequest
|
||||
address_index = 2
|
||||
if is_any_subnetpool_request:
|
||||
prefixlen = subnet['prefixlen']
|
||||
if not attributes.is_attr_set(prefixlen):
|
||||
prefixlen = int(subnetpool['default_prefixlen'])
|
||||
|
||||
return AnySubnetRequest(
|
||||
subnet['tenant_id'],
|
||||
subnet_id,
|
||||
common_utils.ip_version_from_int(subnetpool['ip_version']),
|
||||
prefixlen)
|
||||
else:
|
||||
return SpecificSubnetRequest(subnet['tenant_id'],
|
||||
subnet_id,
|
||||
cidr)
|
||||
|
@ -292,18 +292,33 @@ class TestAddressRequestFactory(base.BaseTestCase):
|
||||
def test_specific_address_request_is_loaded(self):
|
||||
for address in ('10.12.0.15', 'fffe::1'):
|
||||
self.assertIsInstance(
|
||||
ipam.AddressRequestFactory.get_request(address),
|
||||
ipam.AddressRequestFactory.get_request(None,
|
||||
None,
|
||||
address),
|
||||
ipam.SpecificAddressRequest)
|
||||
|
||||
def test_any_address_request_is_loaded(self):
|
||||
for addr in [None, '']:
|
||||
self.assertIsInstance(
|
||||
ipam.AddressRequestFactory.get_request(addr),
|
||||
ipam.AddressRequestFactory.get_request(None,
|
||||
None,
|
||||
addr),
|
||||
ipam.AnyAddressRequest)
|
||||
|
||||
|
||||
class TestSubnetRequestFactory(IpamSubnetRequestTestCase):
|
||||
|
||||
def _build_subnet_dict(self, id=None, cidr='192.168.1.0/24',
|
||||
prefixlen=8, ip_version=4):
|
||||
subnet = {'cidr': cidr,
|
||||
'prefixlen': prefixlen,
|
||||
'ip_version': ip_version,
|
||||
'tenant_id': self.tenant_id,
|
||||
'id': id or self.subnet_id}
|
||||
subnetpool = {'ip_version': ip_version,
|
||||
'default_prefixlen': prefixlen}
|
||||
return subnet, subnetpool
|
||||
|
||||
def test_specific_subnet_request_is_loaded(self):
|
||||
addresses = [
|
||||
'10.12.0.15/24',
|
||||
@ -311,35 +326,34 @@ class TestSubnetRequestFactory(IpamSubnetRequestTestCase):
|
||||
'fffe::1/64',
|
||||
'fffe::/64']
|
||||
for address in addresses:
|
||||
subnet, subnetpool = self._build_subnet_dict(cidr=address)
|
||||
self.assertIsInstance(
|
||||
ipam.SubnetRequestFactory.get_request(self.tenant_id,
|
||||
self.subnet_id,
|
||||
address),
|
||||
ipam.SubnetRequestFactory.get_request(None,
|
||||
subnet,
|
||||
subnetpool),
|
||||
ipam.SpecificSubnetRequest)
|
||||
|
||||
def test_any_address_request_is_loaded_for_ipv4(self):
|
||||
subnet, subnetpool = self._build_subnet_dict(cidr=None, ip_version=4)
|
||||
self.assertIsInstance(
|
||||
ipam.SubnetRequestFactory.get_request(self.tenant_id,
|
||||
self.subnet_id,
|
||||
None,
|
||||
constants.IPv4,
|
||||
8),
|
||||
ipam.SubnetRequestFactory.get_request(None,
|
||||
subnet,
|
||||
subnetpool),
|
||||
ipam.AnySubnetRequest)
|
||||
|
||||
def test_any_address_request_is_loaded_for_ipv6(self):
|
||||
subnet, subnetpool = self._build_subnet_dict(cidr=None, ip_version=6)
|
||||
self.assertIsInstance(
|
||||
ipam.SubnetRequestFactory.get_request(self.tenant_id,
|
||||
self.subnet_id,
|
||||
None,
|
||||
constants.IPv6,
|
||||
64),
|
||||
ipam.SubnetRequestFactory.get_request(None,
|
||||
subnet,
|
||||
subnetpool),
|
||||
ipam.AnySubnetRequest)
|
||||
|
||||
def test_args_are_passed_to_specific_request(self):
|
||||
request = ipam.SubnetRequestFactory.get_request(
|
||||
self.tenant_id,
|
||||
self.subnet_id,
|
||||
'192.168.1.0/24')
|
||||
subnet, subnetpool = self._build_subnet_dict()
|
||||
request = ipam.SubnetRequestFactory.get_request(None,
|
||||
subnet,
|
||||
subnetpool)
|
||||
self.assertIsInstance(request,
|
||||
ipam.SpecificSubnetRequest)
|
||||
self.assertEqual(self.tenant_id, request.tenant_id)
|
||||
|
Loading…
Reference in New Issue
Block a user