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
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):
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()
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):
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:
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
"""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"""
-class SubnetRequestFactory(BaseRequestFactory):
- any_request = AnySubnetRequest
- specific_request = SpecificSubnetRequest
- address_index = 2
+ @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)
+
+ 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)
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',
'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)