Allow IPAM backend switch
Changed inheritance chain for NeutronDbPluginV2 to allow switching from non-pluggable to pluggable IPAM implementation. IpamNonPluggableBackend methods are called on it's instance, instead of previous way where IpamNonPluggableBackend was parent for NeutronDbPluginV2. It allows switching IPAM implementation in set_ipam_backend (IpamNonPluggableBackend to IpamPluggableBackend). All methods that became public in IpamNonPluggableBackend were renamed. This is refactoring step before Pluggable IPAM can be applied. Partially-Implements: blueprint neutron-ipam Change-Id: I81806a43ecc6f0a7b293ce3e70d09d1e266b9f02
This commit is contained in:
parent
1e3b4f119a
commit
b522896c31
@ -228,7 +228,7 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin):
|
|||||||
return self._fields(res, fields)
|
return self._fields(res, fields)
|
||||||
|
|
||||||
def _make_subnet_args(self, shared, detail,
|
def _make_subnet_args(self, shared, detail,
|
||||||
subnet, subnetpool_id=None):
|
subnet, subnetpool_id):
|
||||||
gateway_ip = str(detail.gateway_ip) if detail.gateway_ip else None
|
gateway_ip = str(detail.gateway_ip) if detail.gateway_ip else None
|
||||||
args = {'tenant_id': detail.tenant_id,
|
args = {'tenant_id': detail.tenant_id,
|
||||||
'id': detail.subnet_id,
|
'id': detail.subnet_id,
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_db import api as oslo_db_api
|
|
||||||
from oslo_db import exception as db_exc
|
from oslo_db import exception as db_exc
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
@ -33,6 +32,7 @@ from neutron.common import exceptions as n_exc
|
|||||||
from neutron.common import ipv6_utils
|
from neutron.common import ipv6_utils
|
||||||
from neutron import context as ctx
|
from neutron import context as ctx
|
||||||
from neutron.db import api as db_api
|
from neutron.db import api as db_api
|
||||||
|
from neutron.db import db_base_plugin_common
|
||||||
from neutron.db import ipam_non_pluggable_backend
|
from neutron.db import ipam_non_pluggable_backend
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from neutron.db import sqlalchemyutils
|
from neutron.db import sqlalchemyutils
|
||||||
@ -66,7 +66,7 @@ def _check_subnet_not_used(context, subnet_id):
|
|||||||
raise n_exc.SubnetInUse(subnet_id=subnet_id, reason=e)
|
raise n_exc.SubnetInUse(subnet_id=subnet_id, reason=e)
|
||||||
|
|
||||||
|
|
||||||
class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon,
|
||||||
neutron_plugin_base_v2.NeutronPluginBaseV2):
|
neutron_plugin_base_v2.NeutronPluginBaseV2):
|
||||||
"""V2 Neutron plugin interface implementation using SQLAlchemy models.
|
"""V2 Neutron plugin interface implementation using SQLAlchemy models.
|
||||||
|
|
||||||
@ -84,6 +84,7 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
__native_sorting_support = True
|
__native_sorting_support = True
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.set_ipam_backend()
|
||||||
if cfg.CONF.notify_nova_on_port_status_changes:
|
if cfg.CONF.notify_nova_on_port_status_changes:
|
||||||
from neutron.notifiers import nova
|
from neutron.notifiers import nova
|
||||||
# NOTE(arosen) These event listeners are here to hook into when
|
# NOTE(arosen) These event listeners are here to hook into when
|
||||||
@ -96,6 +97,9 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
event.listen(models_v2.Port.status, 'set',
|
event.listen(models_v2.Port.status, 'set',
|
||||||
self.nova_notifier.record_port_status_changed)
|
self.nova_notifier.record_port_status_changed)
|
||||||
|
|
||||||
|
def set_ipam_backend(self):
|
||||||
|
self.ipam = ipam_non_pluggable_backend.IpamNonPluggableBackend()
|
||||||
|
|
||||||
def _validate_host_route(self, route, ip_version):
|
def _validate_host_route(self, route, ip_version):
|
||||||
try:
|
try:
|
||||||
netaddr.IPNetwork(route['destination'])
|
netaddr.IPNetwork(route['destination'])
|
||||||
@ -439,18 +443,15 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
external_gateway_info}}
|
external_gateway_info}}
|
||||||
l3plugin.update_router(context, id, info)
|
l3plugin.update_router(context, id, info)
|
||||||
|
|
||||||
@oslo_db_api.wrap_db_retry(max_retries=db_api.MAX_RETRIES,
|
|
||||||
retry_on_request=True,
|
|
||||||
retry_on_deadlock=True)
|
|
||||||
def _create_subnet(self, context, subnet, subnetpool_id):
|
def _create_subnet(self, context, subnet, subnetpool_id):
|
||||||
s = subnet['subnet']
|
s = subnet['subnet']
|
||||||
|
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
network = self._get_network(context, s["network_id"])
|
network = self._get_network(context, s["network_id"])
|
||||||
subnet = self._allocate_subnet(context,
|
subnet = self.ipam.allocate_subnet(context,
|
||||||
network,
|
network,
|
||||||
s,
|
s,
|
||||||
subnetpool_id)
|
subnetpool_id)
|
||||||
if hasattr(network, 'external') and network.external:
|
if hasattr(network, 'external') and network.external:
|
||||||
self._update_router_gw_ports(context,
|
self._update_router_gw_ports(context,
|
||||||
network,
|
network,
|
||||||
@ -458,7 +459,7 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
# If this subnet supports auto-addressing, then update any
|
# If this subnet supports auto-addressing, then update any
|
||||||
# internal ports on the network with addresses for this subnet.
|
# internal ports on the network with addresses for this subnet.
|
||||||
if ipv6_utils.is_auto_address_subnet(subnet):
|
if ipv6_utils.is_auto_address_subnet(subnet):
|
||||||
self._add_auto_addrs_on_network_ports(context, subnet)
|
self.ipam.add_auto_addrs_on_network_ports(context, subnet)
|
||||||
return self._make_subnet_dict(subnet)
|
return self._make_subnet_dict(subnet)
|
||||||
|
|
||||||
def _get_subnetpool_id(self, subnet):
|
def _get_subnetpool_id(self, subnet):
|
||||||
@ -514,7 +515,7 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
s['tenant_id'] = self._get_tenant_id_for_create(context, s)
|
s['tenant_id'] = self._get_tenant_id_for_create(context, s)
|
||||||
subnetpool_id = self._get_subnetpool_id(s)
|
subnetpool_id = self._get_subnetpool_id(s)
|
||||||
if subnetpool_id:
|
if subnetpool_id:
|
||||||
self._validate_pools_with_subnetpool(s)
|
self.ipam.validate_pools_with_subnetpool(s)
|
||||||
else:
|
else:
|
||||||
if not has_cidr:
|
if not has_cidr:
|
||||||
msg = _('A cidr must be specified in the absence of a '
|
msg = _('A cidr must be specified in the absence of a '
|
||||||
@ -548,10 +549,11 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
allocation_pools = [{'start': p['first_ip'],
|
allocation_pools = [{'start': p['first_ip'],
|
||||||
'end': p['last_ip']}
|
'end': p['last_ip']}
|
||||||
for p in db_subnet.allocation_pools]
|
for p in db_subnet.allocation_pools]
|
||||||
self._validate_gw_out_of_pools(s["gateway_ip"], allocation_pools)
|
self.ipam.validate_gw_out_of_pools(s["gateway_ip"],
|
||||||
|
allocation_pools)
|
||||||
|
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
subnet, changes = self._update_db_subnet(context, id, s)
|
subnet, changes = self.ipam.update_db_subnet(context, id, s)
|
||||||
result = self._make_subnet_dict(subnet)
|
result = self._make_subnet_dict(subnet)
|
||||||
# Keep up with fields that changed
|
# Keep up with fields that changed
|
||||||
result.update(changes)
|
result.update(changes)
|
||||||
@ -832,7 +834,7 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
db_port = self._create_port_with_mac(
|
db_port = self._create_port_with_mac(
|
||||||
context, network_id, port_data, p['mac_address'])
|
context, network_id, port_data, p['mac_address'])
|
||||||
|
|
||||||
self._allocate_ips_for_port_and_store(context, port, port_id)
|
self.ipam.allocate_ips_for_port_and_store(context, port, port_id)
|
||||||
|
|
||||||
return self._make_port_dict(db_port, process_extensions=False)
|
return self._make_port_dict(db_port, process_extensions=False)
|
||||||
|
|
||||||
@ -859,8 +861,8 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
port = self._get_port(context, id)
|
port = self._get_port(context, id)
|
||||||
new_mac = new_port.get('mac_address')
|
new_mac = new_port.get('mac_address')
|
||||||
self._validate_port_for_update(context, port, new_port, new_mac)
|
self._validate_port_for_update(context, port, new_port, new_mac)
|
||||||
changes = self._update_port_with_ips(context, port,
|
changes = self.ipam.update_port_with_ips(context, port,
|
||||||
new_port, new_mac)
|
new_port, new_mac)
|
||||||
result = self._make_port_dict(port)
|
result = self._make_port_dict(port)
|
||||||
# Keep up with fields that changed
|
# Keep up with fields that changed
|
||||||
if changes.original or changes.add or changes.remove:
|
if changes.original or changes.add or changes.remove:
|
||||||
@ -870,7 +872,7 @@ class NeutronDbPluginV2(ipam_non_pluggable_backend.IpamNonPluggableBackend,
|
|||||||
|
|
||||||
def delete_port(self, context, id):
|
def delete_port(self, context, id):
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
self._delete_port(context, id)
|
self.ipam.delete_port(context, id)
|
||||||
|
|
||||||
def delete_ports_by_device_id(self, context, device_id, network_id=None):
|
def delete_ports_by_device_id(self, context, device_id, network_id=None):
|
||||||
query = (context.session.query(models_v2.Port.id)
|
query = (context.session.query(models_v2.Port.id)
|
||||||
|
@ -52,7 +52,7 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
|
|||||||
return str(netaddr.IPNetwork(cidr_net).network + 1)
|
return str(netaddr.IPNetwork(cidr_net).network + 1)
|
||||||
return subnet.get('gateway_ip')
|
return subnet.get('gateway_ip')
|
||||||
|
|
||||||
def _validate_pools_with_subnetpool(self, subnet):
|
def validate_pools_with_subnetpool(self, subnet):
|
||||||
"""Verifies that allocation pools are set correctly
|
"""Verifies that allocation pools are set correctly
|
||||||
|
|
||||||
Allocation pools can be set for specific subnet request only
|
Allocation pools can be set for specific subnet request only
|
||||||
@ -155,7 +155,7 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
|
|||||||
del s['allocation_pools']
|
del s['allocation_pools']
|
||||||
return result_pools
|
return result_pools
|
||||||
|
|
||||||
def _update_db_subnet(self, context, subnet_id, s):
|
def update_db_subnet(self, context, subnet_id, s):
|
||||||
changes = {}
|
changes = {}
|
||||||
if "dns_nameservers" in s:
|
if "dns_nameservers" in s:
|
||||||
changes['dns_nameservers'] = (
|
changes['dns_nameservers'] = (
|
||||||
@ -298,12 +298,11 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
|
|||||||
|
|
||||||
self._validate_allocation_pools(allocation_pools, cidr)
|
self._validate_allocation_pools(allocation_pools, cidr)
|
||||||
if gateway_ip:
|
if gateway_ip:
|
||||||
self._validate_gw_out_of_pools(gateway_ip,
|
self.validate_gw_out_of_pools(gateway_ip, allocation_pools)
|
||||||
allocation_pools)
|
|
||||||
return [netaddr.IPRange(p['start'], p['end'])
|
return [netaddr.IPRange(p['start'], p['end'])
|
||||||
for p in allocation_pools]
|
for p in allocation_pools]
|
||||||
|
|
||||||
def _validate_gw_out_of_pools(self, gateway_ip, pools):
|
def validate_gw_out_of_pools(self, gateway_ip, pools):
|
||||||
for allocation_pool in pools:
|
for allocation_pool in pools:
|
||||||
pool_range = netaddr.IPRange(
|
pool_range = netaddr.IPRange(
|
||||||
allocation_pool['start'],
|
allocation_pool['start'],
|
||||||
@ -369,7 +368,7 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
|
|||||||
original=prev_ips,
|
original=prev_ips,
|
||||||
remove=remove_ips)
|
remove=remove_ips)
|
||||||
|
|
||||||
def _delete_port(self, context, port_id):
|
def delete_port(self, context, port_id):
|
||||||
query = (context.session.query(models_v2.Port).
|
query = (context.session.query(models_v2.Port).
|
||||||
enable_eagerloads(False).filter_by(id=port_id))
|
enable_eagerloads(False).filter_by(id=port_id))
|
||||||
if not context.is_admin:
|
if not context.is_admin:
|
||||||
@ -403,7 +402,7 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
|
|||||||
nexthop=rt['nexthop'])
|
nexthop=rt['nexthop'])
|
||||||
context.session.add(route)
|
context.session.add(route)
|
||||||
|
|
||||||
self._save_allocation_pools(context, subnet,
|
self.save_allocation_pools(context, subnet,
|
||||||
subnet_request.allocation_pools)
|
subnet_request.allocation_pools)
|
||||||
|
|
||||||
return subnet
|
return subnet
|
||||||
|
@ -186,7 +186,7 @@ class IpamNonPluggableBackend(ipam_backend_mixin.IpamBackendMixin):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _save_allocation_pools(self, context, subnet, allocation_pools):
|
def save_allocation_pools(self, context, subnet, allocation_pools):
|
||||||
for pool in allocation_pools:
|
for pool in allocation_pools:
|
||||||
first_ip = str(netaddr.IPAddress(pool.first, pool.version))
|
first_ip = str(netaddr.IPAddress(pool.first, pool.version))
|
||||||
last_ip = str(netaddr.IPAddress(pool.last, pool.version))
|
last_ip = str(netaddr.IPAddress(pool.last, pool.version))
|
||||||
@ -200,7 +200,7 @@ class IpamNonPluggableBackend(ipam_backend_mixin.IpamBackendMixin):
|
|||||||
last_ip=last_ip)
|
last_ip=last_ip)
|
||||||
context.session.add(ip_range)
|
context.session.add(ip_range)
|
||||||
|
|
||||||
def _allocate_ips_for_port_and_store(self, context, port, port_id):
|
def allocate_ips_for_port_and_store(self, context, port, port_id):
|
||||||
network_id = port['port']['network_id']
|
network_id = port['port']['network_id']
|
||||||
ips = self._allocate_ips_for_port(context, port)
|
ips = self._allocate_ips_for_port(context, port)
|
||||||
if ips:
|
if ips:
|
||||||
@ -210,7 +210,7 @@ class IpamNonPluggableBackend(ipam_backend_mixin.IpamBackendMixin):
|
|||||||
self._store_ip_allocation(context, ip_address, network_id,
|
self._store_ip_allocation(context, ip_address, network_id,
|
||||||
subnet_id, port_id)
|
subnet_id, port_id)
|
||||||
|
|
||||||
def _update_port_with_ips(self, context, db_port, new_port, new_mac):
|
def update_port_with_ips(self, context, db_port, new_port, new_mac):
|
||||||
changes = self.Changes(add=[], original=[], remove=[])
|
changes = self.Changes(add=[], original=[], remove=[])
|
||||||
# Check if the IPs need to be updated
|
# Check if the IPs need to be updated
|
||||||
network_id = db_port['network_id']
|
network_id = db_port['network_id']
|
||||||
@ -431,7 +431,7 @@ class IpamNonPluggableBackend(ipam_backend_mixin.IpamBackendMixin):
|
|||||||
|
|
||||||
return ips
|
return ips
|
||||||
|
|
||||||
def _add_auto_addrs_on_network_ports(self, context, subnet):
|
def add_auto_addrs_on_network_ports(self, context, subnet):
|
||||||
"""For an auto-address subnet, add addrs for ports on the net."""
|
"""For an auto-address subnet, add addrs for ports on the net."""
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
network_id = subnet['network_id']
|
network_id = subnet['network_id']
|
||||||
@ -470,7 +470,7 @@ class IpamNonPluggableBackend(ipam_backend_mixin.IpamBackendMixin):
|
|||||||
ip_address=ip_address)
|
ip_address=ip_address)
|
||||||
return ip_address
|
return ip_address
|
||||||
|
|
||||||
def _allocate_subnet(self, context, network, subnet, subnetpool_id):
|
def allocate_subnet(self, context, network, subnet, subnetpool_id):
|
||||||
subnetpool = None
|
subnetpool = None
|
||||||
if subnetpool_id:
|
if subnetpool_id:
|
||||||
subnetpool = self._get_subnetpool(context, subnetpool_id)
|
subnetpool = self._get_subnetpool(context, subnetpool_id)
|
||||||
|
@ -40,6 +40,7 @@ from neutron.common import ipv6_utils
|
|||||||
from neutron.common import test_lib
|
from neutron.common import test_lib
|
||||||
from neutron.common import utils
|
from neutron.common import utils
|
||||||
from neutron import context
|
from neutron import context
|
||||||
|
from neutron.db import db_base_plugin_common
|
||||||
from neutron.db import db_base_plugin_v2
|
from neutron.db import db_base_plugin_v2
|
||||||
from neutron.db import ipam_non_pluggable_backend as non_ipam
|
from neutron.db import ipam_non_pluggable_backend as non_ipam
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
@ -1626,7 +1627,7 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s
|
|||||||
self.assertEqual(res.status_int,
|
self.assertEqual(res.status_int,
|
||||||
webob.exc.HTTPClientError.code)
|
webob.exc.HTTPClientError.code)
|
||||||
|
|
||||||
@mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2,
|
@mock.patch.object(non_ipam.IpamNonPluggableBackend,
|
||||||
'_allocate_specific_ip')
|
'_allocate_specific_ip')
|
||||||
def test_requested_fixed_ip_address_v6_slaac_router_iface(
|
def test_requested_fixed_ip_address_v6_slaac_router_iface(
|
||||||
self, alloc_specific_ip):
|
self, alloc_specific_ip):
|
||||||
@ -3812,6 +3813,9 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
|
|||||||
'dummy_key', 'dummy_key_table')
|
'dummy_key', 'dummy_key_table')
|
||||||
mock.patch.object(orm.Session, 'add',
|
mock.patch.object(orm.Session, 'add',
|
||||||
side_effect=db_ref_err_for_ipalloc).start()
|
side_effect=db_ref_err_for_ipalloc).start()
|
||||||
|
mock.patch.object(non_ipam.IpamNonPluggableBackend,
|
||||||
|
'_get_subnet',
|
||||||
|
return_value=mock.Mock()).start()
|
||||||
# Add an IPv6 auto-address subnet to the network
|
# Add an IPv6 auto-address subnet to the network
|
||||||
v6_subnet = self._make_subnet(self.fmt, network, 'fe80::1',
|
v6_subnet = self._make_subnet(self.fmt, network, 'fe80::1',
|
||||||
'fe80::/64', ip_version=6,
|
'fe80::/64', ip_version=6,
|
||||||
@ -5374,7 +5378,7 @@ class TestNeutronDbPluginV2(base.BaseTestCase):
|
|||||||
context.session.query.side_effect = return_queries_side_effect
|
context.session.query.side_effect = return_queries_side_effect
|
||||||
subnets = [mock.MagicMock()]
|
subnets = [mock.MagicMock()]
|
||||||
|
|
||||||
db_base_plugin_v2.NeutronDbPluginV2._rebuild_availability_ranges(
|
non_ipam.IpamNonPluggableBackend._rebuild_availability_ranges(
|
||||||
context, subnets)
|
context, subnets)
|
||||||
|
|
||||||
actual = [[args[0].allocation_pool_id,
|
actual = [[args[0].allocation_pool_id,
|
||||||
@ -5437,15 +5441,18 @@ class TestNeutronDbPluginV2(base.BaseTestCase):
|
|||||||
expected)
|
expected)
|
||||||
|
|
||||||
def _test__allocate_ips_for_port(self, subnets, port, expected):
|
def _test__allocate_ips_for_port(self, subnets, port, expected):
|
||||||
|
# this test is incompatible with pluggable ipam, because subnets
|
||||||
|
# were not actually created, so no ipam_subnet exists
|
||||||
|
cfg.CONF.set_override("ipam_driver", None)
|
||||||
plugin = db_base_plugin_v2.NeutronDbPluginV2()
|
plugin = db_base_plugin_v2.NeutronDbPluginV2()
|
||||||
with mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2,
|
with mock.patch.object(db_base_plugin_common.DbBasePluginCommon,
|
||||||
'_get_subnets') as get_subnets:
|
'_get_subnets') as get_subnets:
|
||||||
with mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2,
|
with mock.patch.object(non_ipam.IpamNonPluggableBackend,
|
||||||
'_check_unique_ip') as check_unique:
|
'_check_unique_ip') as check_unique:
|
||||||
context = mock.Mock()
|
context = mock.Mock()
|
||||||
get_subnets.return_value = subnets
|
get_subnets.return_value = subnets
|
||||||
check_unique.return_value = True
|
check_unique.return_value = True
|
||||||
actual = plugin._allocate_ips_for_port(context, port)
|
actual = plugin.ipam._allocate_ips_for_port(context, port)
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
def test__allocate_ips_for_port_2_slaac_subnets(self):
|
def test__allocate_ips_for_port_2_slaac_subnets(self):
|
||||||
@ -5537,7 +5544,7 @@ class NeutronDbPluginV2AsMixinTestCase(NeutronDbPluginV2TestCase,
|
|||||||
ip_version=4)]
|
ip_version=4)]
|
||||||
new_subnetpool_id = None
|
new_subnetpool_id = None
|
||||||
self.assertRaises(n_exc.NetworkSubnetPoolAffinityError,
|
self.assertRaises(n_exc.NetworkSubnetPoolAffinityError,
|
||||||
self.plugin._validate_network_subnetpools,
|
self.plugin.ipam._validate_network_subnetpools,
|
||||||
network, new_subnetpool_id, 4)
|
network, new_subnetpool_id, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1577,6 +1577,8 @@ class TestMl2PluginCreateUpdateDeletePort(base.BaseTestCase):
|
|||||||
'get_service_plugins',
|
'get_service_plugins',
|
||||||
return_value={'L3_ROUTER_NAT': l3plugin}):
|
return_value={'L3_ROUTER_NAT': l3plugin}):
|
||||||
plugin = self._create_plugin_for_create_update_port(mock.Mock())
|
plugin = self._create_plugin_for_create_update_port(mock.Mock())
|
||||||
|
# Set backend manually here since __init__ was mocked
|
||||||
|
plugin.set_ipam_backend()
|
||||||
# deleting the port will call registry.notify, which will
|
# deleting the port will call registry.notify, which will
|
||||||
# run the transaction balancing function defined in this test
|
# run the transaction balancing function defined in this test
|
||||||
plugin.delete_port(self.context, 'fake_id')
|
plugin.delete_port(self.context, 'fake_id')
|
||||||
|
2
neutron/tests/unit/test_ipam.py
Executable file → Normal file
2
neutron/tests/unit/test_ipam.py
Executable file → Normal file
@ -314,6 +314,8 @@ class TestSubnetRequestFactory(IpamSubnetRequestTestCase):
|
|||||||
'prefixlen': prefixlen,
|
'prefixlen': prefixlen,
|
||||||
'ip_version': ip_version,
|
'ip_version': ip_version,
|
||||||
'tenant_id': self.tenant_id,
|
'tenant_id': self.tenant_id,
|
||||||
|
'gateway_ip': None,
|
||||||
|
'allocation_pools': None,
|
||||||
'id': id or self.subnet_id}
|
'id': id or self.subnet_id}
|
||||||
subnetpool = {'ip_version': ip_version,
|
subnetpool = {'ip_version': ip_version,
|
||||||
'default_prefixlen': prefixlen}
|
'default_prefixlen': prefixlen}
|
||||||
|
Loading…
Reference in New Issue
Block a user