summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-03-17 01:38:19 +0000
committerGerrit Code Review <review@openstack.org>2018-03-17 01:38:19 +0000
commit93330aca08c30febe8318b3054177d7458fa5283 (patch)
tree0b904e5d0c8aa5af2c25e700e350ed152d186355
parent0f46559557c0942b69503b4dd357d68132da0762 (diff)
parentfb5c2ba3390668afeca828681edc54fb544cef11 (diff)
downloadneutron-10.0.6.tar.gz
Merge "Always pass device_owner to _ipam_get_subnets()" into stable/ocata10.0.6
-rw-r--r--neutron/db/ipam_backend_mixin.py6
-rw-r--r--neutron/ipam/exceptions.py3
-rw-r--r--neutron/tests/unit/extensions/test_subnet_service_types.py27
3 files changed, 32 insertions, 4 deletions
diff --git a/neutron/db/ipam_backend_mixin.py b/neutron/db/ipam_backend_mixin.py
index 7b448e4be4..e9caee9801 100644
--- a/neutron/db/ipam_backend_mixin.py
+++ b/neutron/db/ipam_backend_mixin.py
@@ -695,7 +695,8 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
# subnets. Happens on routed networks when host isn't known.
raise ipam_exceptions.DeferIpam()
- raise ipam_exceptions.IpAddressGenerationFailureNoMatchingSubnet()
+ raise ipam_exceptions.IpAddressGenerationFailureNoMatchingSubnet(
+ network_id=network_id, service_type=service_type)
def _find_candidate_subnets(self, context, network_id, host, service_type,
fixed_configured):
@@ -775,7 +776,8 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
new_host_requested = host and host != old_host
if old_ips and new_host_requested and not fixed_ips_requested:
valid_subnets = self._ipam_get_subnets(
- context, old_port['network_id'], host)
+ context, old_port['network_id'], host,
+ service_type=old_port.get('device_owner'))
valid_subnet_ids = {s['id'] for s in valid_subnets}
for fixed_ip in old_ips:
if fixed_ip['subnet_id'] not in valid_subnet_ids:
diff --git a/neutron/ipam/exceptions.py b/neutron/ipam/exceptions.py
index feb93a7f80..250ca7aad2 100644
--- a/neutron/ipam/exceptions.py
+++ b/neutron/ipam/exceptions.py
@@ -69,7 +69,8 @@ class IpAddressGenerationFailureAllSubnets(IpAddressGenerationFailure):
class IpAddressGenerationFailureNoMatchingSubnet(IpAddressGenerationFailure):
- message = _("No valid service subnet for the given device owner.")
+ message = _("No valid service subnet for the given device owner, "
+ "network %(network_id)s, service type %(service_type)s.")
class IPAllocationFailed(exceptions.NeutronException):
diff --git a/neutron/tests/unit/extensions/test_subnet_service_types.py b/neutron/tests/unit/extensions/test_subnet_service_types.py
index 59e421ff33..fe78a01867 100644
--- a/neutron/tests/unit/extensions/test_subnet_service_types.py
+++ b/neutron/tests/unit/extensions/test_subnet_service_types.py
@@ -12,6 +12,8 @@
import webob.exc
+from neutron_lib.api.definitions import portbindings
+
from neutron.db import db_base_plugin_v2
from neutron.extensions import subnet_service_types
from neutron.tests.unit.db import test_db_base_plugin_v2
@@ -38,7 +40,7 @@ class SubnetServiceTypesExtensionTestPlugin(
"""Test plugin to mixin the subnet service_types extension.
"""
- supported_extension_aliases = ["subnet-service-types"]
+ supported_extension_aliases = ["subnet-service-types", "binding"]
class SubnetServiceTypesExtensionTestCase(
@@ -322,6 +324,29 @@ class SubnetServiceTypesExtensionTestCase(
# applied
port = self._update('ports', port['id'], data)
+ def test_update_port_host_binding(self):
+ with self.network() as network:
+ pass
+ service_type = 'compute:foo'
+ # Create a subnet with a service_type
+ self._create_service_subnet([service_type],
+ cidr=self.CIDRS[1],
+ network=network)
+ # Create a port with a matching device owner
+ network = network['network']
+ port = self._create_port(self.fmt,
+ net_id=network['id'],
+ tenant_id=network['tenant_id'],
+ device_owner=service_type,
+ arg_list=(portbindings.HOST_ID,),
+ **{portbindings.HOST_ID: 'fakehost'})
+ port = self.deserialize('json', port)['port']
+ # Update the port's host binding.
+ data = {'port': {portbindings.HOST_ID: 'fakehost2'}}
+ # self._update will fail with a MismatchError if the update cannot be
+ # applied
+ port = self._update('ports', port['id'], data)
+
class SubnetServiceTypesExtensionTestCasev6(
SubnetServiceTypesExtensionTestCase):