Merge "Always pass device_owner to _ipam_get_subnets()"

This commit is contained in:
Zuul 2018-02-17 02:10:56 +00:00 committed by Gerrit Code Review
commit 6b3ae884dc
3 changed files with 32 additions and 4 deletions

View File

@ -692,7 +692,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):
@ -773,7 +774,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:

View File

@ -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):

View File

@ -12,6 +12,8 @@
import webob.exc
from neutron_lib.api.definitions import portbindings
from neutron.db import db_base_plugin_v2
from neutron.db import subnet_service_type_db_models
from neutron.extensions import subnet_service_types
@ -40,7 +42,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(
@ -324,6 +326,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):