diff --git a/nova/compute/manager.py b/nova/compute/manager.py index b066b6cc011d..f55ef9b16513 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -8046,7 +8046,7 @@ class ComputeManager(manager.Manager): LOG.info('Destination was ready for NUMA live migration, ' 'but source is either too old, or is set to an ' 'older upgrade level.', instance=instance) - if self.network_api.supports_port_binding_extension(ctxt): + if self.network_api.has_port_binding_extension(ctxt): # Create migrate_data vifs if not provided by driver. if 'vifs' not in migrate_data: migrate_data.vifs = ( diff --git a/nova/conductor/tasks/cross_cell_migrate.py b/nova/conductor/tasks/cross_cell_migrate.py index d66394cb6e32..e04378f805c6 100644 --- a/nova/conductor/tasks/cross_cell_migrate.py +++ b/nova/conductor/tasks/cross_cell_migrate.py @@ -698,7 +698,7 @@ class CrossCellMigrationTask(base.TaskBase): LOG.debug('Making sure neutron is new enough for cross-cell resize.') # Check that the port binding-extended API extension is available in # neutron because if it's not we can just fail fast. - if not self.network_api.supports_port_binding_extension(self.context): + if not self.network_api.has_port_binding_extension(self.context): raise exception.MigrationPreCheckError( reason=_("Required networking service API extension '%s' " "not found.") % diff --git a/nova/conductor/tasks/live_migrate.py b/nova/conductor/tasks/live_migrate.py index 294abfe4e342..1acae88b2645 100644 --- a/nova/conductor/tasks/live_migrate.py +++ b/nova/conductor/tasks/live_migrate.py @@ -245,8 +245,7 @@ class LiveMigrationTask(base.TaskBase): "are not allowed for live migration.") # All PCI requests are VIF related, now check neutron, # source and destination compute nodes. - if not self.network_api.supports_port_binding_extension( - self.context): + if not self.network_api.has_port_binding_extension(self.context): raise exception.MigrationPreCheckError( reason="Cannot live migrate VIF with related PCI, Neutron " "does not support required port binding extension.") @@ -366,7 +365,7 @@ class LiveMigrationTask(base.TaskBase): raise exception.MigrationPreCheckError(msg) # Check to see that neutron supports the binding-extended API. - if self.network_api.supports_port_binding_extension(self.context): + if self.network_api.has_port_binding_extension(self.context): bindings = self._bind_ports_on_destination( destination, provider_mapping) self._update_migrate_vifs_from_bindings(self.migrate_data.vifs, diff --git a/nova/network/constants.py b/nova/network/constants.py index 4a08c870f6c6..eff49022c16a 100644 --- a/nova/network/constants.py +++ b/nova/network/constants.py @@ -13,23 +13,40 @@ # License for the specific language governing permissions and limitations # under the License. -QOS_QUEUE = 'QoS Queue' -NET_EXTERNAL = 'router:external' -VNIC_INDEX_EXT = 'VNIC Index' -DNS_INTEGRATION = 'DNS Integration' -MULTI_NET_EXT = 'Multi Provider Network' -FIP_PORT_DETAILS = 'Floating IP Port Details Extension' -SUBSTR_PORT_FILTERING = 'IP address substring filtering' -PORT_BINDING = 'Port Binding' -PORT_BINDING_EXTENDED = 'Port Bindings Extended' -DEFAULT_SECGROUP = 'default' +# Port fields + BINDING_PROFILE = 'binding:profile' BINDING_HOST_ID = 'binding:host_id' -MIGRATING_ATTR = 'migrating_to' -L3_NETWORK_TYPES = ['vxlan', 'gre', 'geneve'] -ALLOCATION = 'allocation' RESOURCE_REQUEST = 'resource_request' REQUEST_GROUPS = 'request_groups' -SEGMENT = 'Segment' NUMA_POLICY = 'numa_affinity_policy' -RESOURCE_REQUEST_GROUPS_EXTENSION = "Port Resource Request Groups" + +# Binding profile fields + +MIGRATING_ATTR = 'migrating_to' +ALLOCATION = 'allocation' + +# Core extensions + +DNS_INTEGRATION = 'dns-integration' +MULTI_PROVIDER = 'multi-provider' +FIP_PORT_DETAILS = 'fip-port-details' +PORT_BINDING = 'binding' +PORT_BINDING_EXTENDED = 'binding-extended' +SUBSTR_PORT_FILTERING = 'ip-substring-filtering' +SEGMENT = 'segment' +RESOURCE_REQUEST_GROUPS = 'port-resource-request-groups' + +# Third-party extensions + +VNIC_INDEX = 'vnic-index' # this is provided by the vmware_nsx project +QOS_QUEUE = 'qos-queue' # TODO(stephenfin): what defines this? Xen? + +# Search fields + +NET_EXTERNAL = 'router:external' + +# Misc + +DEFAULT_SECGROUP = 'default' +L3_NETWORK_TYPES = ['vxlan', 'gre', 'geneve'] diff --git a/nova/network/neutron.py b/nova/network/neutron.py index 294ccaebbecb..a3c7afdb7c60 100644 --- a/nova/network/neutron.py +++ b/nova/network/neutron.py @@ -382,7 +382,8 @@ class API: # If a host was provided, delete any bindings between that # host and the ports as long as the host isn't the same as # the current instance.host. - has_binding_ext = self.supports_port_binding_extension(context) + has_binding_ext = self.has_port_binding_extension( + client=admin_client) if port_migrating and has_binding_ext: self._delete_port_bindings(context, ports, host) elif port_migrating: @@ -676,8 +677,12 @@ class API: # NOTE: For internal DNS integration (network does not have a # dns_domain), or if we cannot retrieve network info, we use the # admin client to reset dns_name. - if self._has_dns_extension() and not network.get('dns_domain'): + if ( + self.has_dns_extension(client=port_client) and + not network.get('dns_domain') + ): port_req_body['port']['dns_name'] = '' + try: port_client.update_port(port_id, port_req_body) except neutron_client_exc.PortNotFoundClient: @@ -1334,62 +1339,112 @@ class API: return (nets_in_requested_order, ports_in_requested_order, preexisting_port_ids, created_port_ids) - def _refresh_neutron_extensions_cache(self, context, neutron=None): + def _refresh_neutron_extensions_cache(self, client): """Refresh the neutron extensions cache when necessary.""" if (not self.last_neutron_extension_sync or ((time.time() - self.last_neutron_extension_sync) >= CONF.neutron.extension_sync_interval)): - if neutron is None: - neutron = get_client(context) - extensions_list = neutron.list_extensions()['extensions'] + extensions_list = client.list_extensions()['extensions'] self.last_neutron_extension_sync = time.time() self.extensions.clear() - self.extensions = {ext['name']: ext for ext in extensions_list} + self.extensions = {ext['alias']: ext for ext in extensions_list} - def _has_multi_provider_extension(self, context, neutron=None): - self._refresh_neutron_extensions_cache(context, neutron=neutron) - return constants.MULTI_NET_EXT in self.extensions + def _has_extension(self, extension, context=None, client=None): + """Check if the provided neutron extension is enabled. - def _has_dns_extension(self): - return constants.DNS_INTEGRATION in self.extensions + :param extension: The alias of the extension to check + :param client: keystoneauth1.adapter.Adapter + :param context: nova.context.RequestContext + :returns: True if the neutron extension is available, else False + """ + if client is None: + client = get_client(context) - def _has_qos_queue_extension(self, context, neutron=None): - self._refresh_neutron_extensions_cache(context, neutron=neutron) - return constants.QOS_QUEUE in self.extensions + self._refresh_neutron_extensions_cache(client) + return extension in self.extensions - def _has_fip_port_details_extension(self, context, neutron=None): - self._refresh_neutron_extensions_cache(context, neutron=neutron) - return constants.FIP_PORT_DETAILS in self.extensions + def has_multi_provider_extension(self, context=None, client=None): + """Check if the 'multi-provider' extension is enabled. - def has_substr_port_filtering_extension(self, context): - self._refresh_neutron_extensions_cache(context) - return constants.SUBSTR_PORT_FILTERING in self.extensions + This extension allows administrative users to define multiple physical + bindings for a logical network. + """ + return self._has_extension(constants.MULTI_PROVIDER, context, client) - def _has_segment_extension(self, context, neutron=None): - self._refresh_neutron_extensions_cache(context, neutron=neutron) - return constants.SEGMENT in self.extensions + def has_dns_extension(self, context=None, client=None): + """Check if the 'dns-integration' extension is enabled. + + This extension adds the 'dns_name' and 'dns_assignment' attributes to + port resources. + """ + return self._has_extension(constants.DNS_INTEGRATION, context, client) # TODO(gibi): Remove all branches where this is False after Neutron made # the this extension mandatory. In Xena this extension will be optional to # support the scenario where Neutron upgraded first. So Neutron can mark # this mandatory earliest in Yoga. - def has_extended_resource_request_extension(self, context, neutron=None): - self._refresh_neutron_extensions_cache(context, neutron=neutron) - return constants.RESOURCE_REQUEST_GROUPS_EXTENSION in self.extensions + def has_extended_resource_request_extension( + self, context=None, client=None, + ): + return self._has_extension( + constants.RESOURCE_REQUEST_GROUPS, context, client, + ) - def supports_port_binding_extension(self, context): - """This is a simple check to see if the neutron "binding-extended" - extension exists and is enabled. + # TODO(stephenfin): This is optionally used by the XenAPI virt driver, but + # I can't find what defines it and suspect it's dead code. Consider + # removing the functionality + def has_qos_queue_extension(self, context=None, client=None): + """Check if the 'qos-queue' extension is enabled. - The "binding-extended" extension allows nova to bind a port to multiple - hosts at the same time, like during live migration. - - :param context: the user request context - :returns: True if the binding-extended API extension is available, - False otherwise + This extension is provided by a XenServer neutron plugin...we think. """ - self._refresh_neutron_extensions_cache(context) - return constants.PORT_BINDING_EXTENDED in self.extensions + return self._has_extension(constants.QOS_QUEUE, context, client) + + def has_vnic_index_extension(self, context=None, client=None): + """Check if the 'vnic-index' extension is enabled. + + This extension is provided by the VMWare NSX neutron plugin. + """ + return self._has_extension(constants.VNIC_INDEX, context, client) + + def has_fip_port_details_extension(self, context=None, client=None): + """Check if the 'fip-port-details' extension is enabled. + + This extension adds the 'port_details' attribute to floating IPs. + """ + return self._has_extension(constants.FIP_PORT_DETAILS, context, client) + + def has_substr_port_filtering_extension(self, context=None, client=None): + """Check if the 'ip-substring-filtering' extension is enabled. + + This extension adds support for filtering ports by using part of an IP + address. + """ + return self._has_extension( + constants.SUBSTR_PORT_FILTERING, context, client + ) + + def has_segment_extension(self, context=None, client=None): + """Check if the neutron 'segment' extension is enabled. + + This extension exposes information about L2 segments of a network. + """ + return self._has_extension( + constants.SEGMENT, context, client, + ) + + def has_port_binding_extension(self, context=None, client=None): + """Check if the neutron 'binding-extended' extension is enabled. + + This extensions exposes port bindings of a virtual port to external + application. + + This extension allows nova to bind a port to multiple hosts at the same + time, like during live migration. + """ + return self._has_extension( + constants.PORT_BINDING_EXTENDED, context, client + ) def bind_ports_to_host(self, context, instance, host, vnic_types=None, port_profiles=None): @@ -1403,7 +1458,7 @@ class API: In the event of an error, any ports which were successfully bound to the host should have those host bindings removed from the ports. - This method should not be used if "supports_port_binding_extension" + This method should not be used if "has_port_binding_extension" returns False. :param context: the user request context @@ -1482,7 +1537,7 @@ class API: def delete_port_binding(self, context, port_id, host): """Delete the port binding for the given port ID and host - This method should not be used if "supports_port_binding_extension" + This method should not be used if "has_port_binding_extension" returns False. :param context: The request context for the operation. @@ -1602,7 +1657,10 @@ class API: If the extensions loaded contain QOS_QUEUE then pass the rxtx_factor. """ - if self._has_qos_queue_extension(context, neutron=neutron): + if neutron is None: + neutron = get_client(context) + + if self.has_qos_queue_extension(client=neutron): flavor = instance.get_flavor() rxtx_factor = flavor.get('rxtx_factor') port_req_body['port']['rxtx_factor'] = rxtx_factor @@ -1612,7 +1670,7 @@ class API: port_req_body, port_arq) - if self._has_dns_extension(): + if self.has_dns_extension(client=neutron): # If the DNS integration extension is enabled in Neutron, most # ports will get their dns_name attribute set in the port create or # update requests in allocate_for_instance. So we just add the @@ -1638,7 +1696,8 @@ class API: an additional update request. Only a very small fraction of ports will require this additional update request. """ - if self._has_dns_extension() and network.get('dns_domain'): + if self.has_dns_extension(client=neutron) and network.get( + 'dns_domain'): try: port_req_body = {'port': {'dns_name': instance.hostname}} neutron.update_port(port_id, port_req_body) @@ -1650,7 +1709,7 @@ class API: 'name') % {'hostname': instance.hostname}) raise exception.InvalidInput(reason=msg) - def _reset_port_dns_name(self, network, port_id, neutron_client): + def _reset_port_dns_name(self, network, port_id, client): """Reset an instance port dns_name attribute to empty when using external DNS service. @@ -1660,10 +1719,11 @@ class API: request with a Neutron client using user's context, so that the DNS record can be found under user's zone and domain. """ - if self._has_dns_extension() and network.get('dns_domain'): + if self.has_dns_extension(client=client) and network.get( + 'dns_domain'): try: port_req_body = {'port': {'dns_name': ''}} - neutron_client.update_port(port_id, port_req_body) + client.update_port(port_id, port_req_body) except neutron_client_exc.NeutronClientException: LOG.exception("Failed to reset dns_name for port %s", port_id) @@ -2037,7 +2097,7 @@ class API: segments, the first segment that defines a physnet value will be used for the physnet name. """ - if self._has_multi_provider_extension(context, neutron=neutron): + if self.has_multi_provider_extension(client=neutron): network = neutron.show_network(net_id, fields='segments').get('network') segments = network.get('segments', {}) @@ -2712,7 +2772,7 @@ class API: # ...and retrieve the port details for the same reason, but only if # they're not already there because the fip-port-details extension is # present - if not self._has_fip_port_details_extension(context, client): + if not self.has_fip_port_details_extension(client=client): port_id = fip['port_id'] try: fip['port_details'] = client.show_port( @@ -2740,7 +2800,7 @@ class API: # ...and retrieve the port details for the same reason, but only if # they're not already there because the fip-port-details extension is # present - if not self._has_fip_port_details_extension(context, client): + if not self.has_fip_port_details_extension(client=client): port_id = fip['port_id'] try: fip['port_details'] = client.show_port( @@ -2779,7 +2839,7 @@ class API: # ...and retrieve the port details for the same reason, but only if # they're not already there because the fip-port-details extension is # present - if not self._has_fip_port_details_extension(context, client): + if not self.has_fip_port_details_extension(client=client): ports = {port['id']: port for port in client.list_ports( **{'tenant_id': project_id})['ports']} for fip in fips: @@ -2975,7 +3035,7 @@ class API: :raises: nova.exception.PortBindingActivationFailed if any port binding activation fails """ - if not self.supports_port_binding_extension(context): + if not self.has_port_binding_extension(context): # If neutron isn't new enough yet for the port "binding-extended" # API extension, we just no-op. The port binding host will be # be updated in migrate_instance_finish, which is functionally OK, @@ -3501,7 +3561,8 @@ class API: :raises: PortBindingDeletionFailed if port binding deletion fails. """ # First check to see if the port binding extension is supported. - if not self.supports_port_binding_extension(context): + client = get_client(context) + if not self.has_port_binding_extension(client=client): LOG.info("Neutron extension '%s' is not supported; not cleaning " "up port bindings for host %s.", constants.PORT_BINDING_EXTENDED, host, instance=instance) @@ -3692,9 +3753,8 @@ class API: :param vif: The VIF in question. :param index: The index on the instance for the VIF. """ - self._refresh_neutron_extensions_cache(context) - if constants.VNIC_INDEX_EXT in self.extensions: - neutron = get_client(context) + neutron = get_client(context) + if self.has_vnic_index_extension(client=neutron): port_req_body = {'port': {'vnic_index': index}} try: neutron.update_port(vif['id'], port_req_body) @@ -3717,10 +3777,11 @@ class API: either Segment extension isn't enabled in Neutron or if the network isn't configured for routing. """ - if not self._has_segment_extension(context): + client = get_client(context) + + if not self.has_segment_extension(client=client): return [] - client = get_client(context) try: # NOTE(sbauza): We can't use list_segments() directly because the # API is borked and returns both segments but also segmentation IDs @@ -3747,10 +3808,11 @@ class API: extension isn't enabled in Neutron or the provided subnet doesn't have segments (if the related network isn't configured for routing) """ - if not self._has_segment_extension(context): + client = get_client(context) + + if not self.has_segment_extension(client=client): return None - client = get_client(context) try: subnet = client.show_subnet(subnet_id)['subnet'] except neutron_client_exc.NeutronClientException as e: diff --git a/nova/tests/functional/regressions/test_bug_1888395.py b/nova/tests/functional/regressions/test_bug_1888395.py index 36eb0e0f52b3..e582ad3e8519 100644 --- a/nova/tests/functional/regressions/test_bug_1888395.py +++ b/nova/tests/functional/regressions/test_bug_1888395.py @@ -108,7 +108,7 @@ class TestLiveMigrationWithoutMultiplePortBindings( networks=[{'port': self.neutron.port_1['id']}]) self.assertFalse( - self.neutron_api.supports_port_binding_extension(self.ctxt)) + self.neutron_api.has_port_binding_extension(self.ctxt)) # TODO(sean-k-mooney): extend _live_migrate to support passing a host self.api.post_server_action( server['id'], diff --git a/nova/tests/functional/test_servers_resource_request.py b/nova/tests/functional/test_servers_resource_request.py index a8df84a5bcf0..1fb39ac98a8b 100644 --- a/nova/tests/functional/test_servers_resource_request.py +++ b/nova/tests/functional/test_servers_resource_request.py @@ -146,12 +146,13 @@ class ExtendedResourceRequestNeutronFixture(ResourceRequestNeutronFixture): # port_resource_request_groups.py { "updated": "2021-08-02T10:00:00-00:00", - "name": constants.RESOURCE_REQUEST_GROUPS_EXTENSION, + "name": "Port Resource Request Groups", "links": [], "alias": "port-resource-request-groups", - "description": + "description": ( "Support requesting multiple groups of resources and " "traits from the same RP subtree in resource_request" + ), } ) return extensions diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index f65f1abdb740..1d877e0900ec 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -6066,10 +6066,9 @@ class ComputeTestCase(BaseTestCase, return fake_network.fake_get_instance_nw_info(self) self.stub_out('nova.network.neutron.API.get_instance_nw_info', stupid) - self.useFixture( - std_fixtures.MonkeyPatch( - 'nova.network.neutron.API.supports_port_binding_extension', - lambda *args: True)) + self.useFixture(std_fixtures.MonkeyPatch( + 'nova.network.neutron.API.has_port_binding_extension', + lambda *args: True)) # creating instance testdata instance = self._create_fake_instance_obj({'host': 'dummy'}) c = context.get_admin_context() diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index 4d7967b37e48..836755b4e68d 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -3460,7 +3460,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, side_effect=exception.InstanceGroupNotFound(group_uuid=''))) def test_check_can_live_migrate_destination_success(self): self.useFixture(std_fixtures.MonkeyPatch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', lambda *args: True)) self._test_check_can_live_migrate_destination() @@ -3468,7 +3468,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, side_effect=exception.InstanceGroupNotFound(group_uuid=''))) def test_check_can_live_migrate_destination_fail(self): self.useFixture(std_fixtures.MonkeyPatch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', lambda *args: True)) self.assertRaises( test.TestingException, @@ -3479,7 +3479,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, side_effect=exception.InstanceGroupNotFound(group_uuid=''))) def test_check_can_live_migrate_destination_contains_vifs(self): self.useFixture(std_fixtures.MonkeyPatch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', lambda *args: True)) migrate_data = self._test_check_can_live_migrate_destination() self.assertIn('vifs', migrate_data) @@ -3489,7 +3489,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, side_effect=exception.InstanceGroupNotFound(group_uuid=''))) def test_check_can_live_migrate_destination_no_binding_extended(self): self.useFixture(std_fixtures.MonkeyPatch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', lambda *args: False)) migrate_data = self._test_check_can_live_migrate_destination() self.assertNotIn('vifs', migrate_data) @@ -3498,7 +3498,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, side_effect=exception.InstanceGroupNotFound(group_uuid=''))) def test_check_can_live_migrate_destination_src_numa_lm_false(self): self.useFixture(std_fixtures.MonkeyPatch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', lambda *args: True)) self._test_check_can_live_migrate_destination(src_numa_lm=False) @@ -3506,7 +3506,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, side_effect=exception.InstanceGroupNotFound(group_uuid=''))) def test_check_can_live_migrate_destination_src_numa_lm_true(self): self.useFixture(std_fixtures.MonkeyPatch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', lambda *args: True)) self._test_check_can_live_migrate_destination(src_numa_lm=True) diff --git a/nova/tests/unit/conductor/tasks/test_cross_cell_migrate.py b/nova/tests/unit/conductor/tasks/test_cross_cell_migrate.py index 127d76347795..ec07e6f55fae 100644 --- a/nova/tests/unit/conductor/tasks/test_cross_cell_migrate.py +++ b/nova/tests/unit/conductor/tasks/test_cross_cell_migrate.py @@ -439,7 +439,7 @@ class CrossCellMigrationTaskTestCase(test.NoDBTestCase): what we need. """ with mock.patch.object( - self.task.network_api, 'supports_port_binding_extension', + self.task.network_api, 'has_port_binding_extension', return_value=True) as mock_neutron_check: self.task._perform_external_api_checks() mock_neutron_check.assert_called_once_with(self.task.context) @@ -447,7 +447,7 @@ class CrossCellMigrationTaskTestCase(test.NoDBTestCase): def test_perform_external_api_checks_old_neutron(self): """Tests the case that neutron API is old.""" with mock.patch.object( - self.task.network_api, 'supports_port_binding_extension', + self.task.network_api, 'has_port_binding_extension', return_value=False): ex = self.assertRaises(exception.MigrationPreCheckError, self.task._perform_external_api_checks) diff --git a/nova/tests/unit/conductor/tasks/test_live_migrate.py b/nova/tests/unit/conductor/tasks/test_live_migrate.py index 88f00d0d84aa..cb40c076c82d 100644 --- a/nova/tests/unit/conductor/tasks/test_live_migrate.py +++ b/nova/tests/unit/conductor/tasks/test_live_migrate.py @@ -353,7 +353,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): with test.nested( mock.patch.object(self.task.network_api, - 'supports_port_binding_extension', + 'has_port_binding_extension', return_value=False), mock.patch.object(self.task, '_check_can_migrate_pci')): self.assertIsNone(self.task._check_requested_destination()) @@ -387,7 +387,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): with test.nested( mock.patch.object(self.task.network_api, - 'supports_port_binding_extension', + 'has_port_binding_extension', return_value=False), mock.patch.object(self.task, '_check_can_migrate_pci')): ex = self.assertRaises(exception.MigrationPreCheckError, @@ -813,7 +813,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): """ @mock.patch.object(self.task.network_api, - 'supports_port_binding_extension') + 'has_port_binding_extension') @mock.patch.object(live_migrate, 'supports_vif_related_pci_allocations') def _test(instance_pci_reqs, diff --git a/nova/tests/unit/network/test_neutron.py b/nova/tests/unit/network/test_neutron.py index a06549b609c6..433966ae1a27 100644 --- a/nova/tests/unit/network/test_neutron.py +++ b/nova/tests/unit/network/test_neutron.py @@ -515,7 +515,11 @@ class TestAPIBase(test.TestCase): has_dns_extension = False if kwargs.get('dns_extension'): has_dns_extension = True - self.api.extensions[constants.DNS_INTEGRATION] = 1 + self.api.extensions = { + constants.DNS_INTEGRATION: { + 'alias': constants.DNS_INTEGRATION, + }, + } # Net idx is 1-based for compatibility with existing unit tests nets = self.nets[net_idx - 1] @@ -1167,17 +1171,14 @@ class TestAPI(TestAPIBase): mock_get_physnet.assert_called_once_with( mock.ANY, mock.ANY, self.port_data1[0]['network_id']) - @mock.patch.object(neutronapi, 'get_client') - def test_refresh_neutron_extensions_cache(self, mock_get_client): + def test_refresh_neutron_extensions_cache(self): mocked_client = mock.create_autospec(client.Client) - mock_get_client.return_value = mocked_client mocked_client.list_extensions.return_value = { - 'extensions': [{'name': constants.QOS_QUEUE}]} - self.api._refresh_neutron_extensions_cache(self.context) + 'extensions': [{'alias': constants.QOS_QUEUE}]} + self.api._refresh_neutron_extensions_cache(mocked_client) self.assertEqual( - {constants.QOS_QUEUE: {'name': constants.QOS_QUEUE}}, + {constants.QOS_QUEUE: {'alias': constants.QOS_QUEUE}}, self.api.extensions) - mock_get_client.assert_called_once_with(self.context) mocked_client.list_extensions.assert_called_once_with() @mock.patch.object(neutronapi, 'get_client') @@ -1186,7 +1187,7 @@ class TestAPI(TestAPIBase): mocked_client = mock.create_autospec(client.Client) mock_get_client.return_value = mocked_client mocked_client.list_extensions.return_value = { - 'extensions': [{'name': constants.QOS_QUEUE}]} + 'extensions': [{'alias': constants.QOS_QUEUE}]} flavor = objects.Flavor.get_by_name(self.context, 'm1.small') flavor['rxtx_factor'] = 1 instance = objects.Instance(system_metadata={}) @@ -2415,9 +2416,13 @@ class TestAPI(TestAPIBase): mock_nc.show_port.side_effect = exceptions.PortNotFoundClient if fip_ext_enabled: - self.api.extensions = [constants.FIP_PORT_DETAILS] + self.api.extensions = { + constants.FIP_PORT_DETAILS: { + 'alias': constants.FIP_PORT_DETAILS, + }, + } else: - self.api.extensions = [] + self.api.extensions = {} fip = self.api.get_floating_ip(self.context, uuids.fip_id) @@ -2490,9 +2495,13 @@ class TestAPI(TestAPIBase): mock_nc.show_port.side_effect = exceptions.PortNotFoundClient if fip_ext_enabled: - self.api.extensions = [constants.FIP_PORT_DETAILS] + self.api.extensions = { + constants.FIP_PORT_DETAILS: { + 'alias': constants.FIP_PORT_DETAILS, + }, + } else: - self.api.extensions = [] + self.api.extensions = {} fip = self.api.get_floating_ip_by_address(self.context, '172.1.2.3') @@ -3474,7 +3483,7 @@ class TestAPI(TestAPIBase): 'provider:network_type': 'vxlan'}]}} test_ext_list = {'extensions': [{'name': 'Multi Provider Network', - 'alias': 'multi-segments'}]} + 'alias': 'multi-provider'}]} mock_client = mock_get_client.return_value mock_client.list_extensions.return_value = test_ext_list @@ -3495,7 +3504,7 @@ class TestAPI(TestAPIBase): 'provider:network_type': 'vlan'}} test_ext_list = {'extensions': [{'name': 'Multi Provider Network', - 'alias': 'multi-segments'}]} + 'alias': 'multi-provider'}]} mock_client = mock_get_client.return_value mock_client.list_extensions.return_value = test_ext_list @@ -3521,7 +3530,7 @@ class TestAPI(TestAPIBase): 'provider:network_type': 'vlan'}]}} test_ext_list = {'extensions': [{'name': 'Multi Provider Network', - 'alias': 'multi-segments'}]} + 'alias': 'multi-provider'}]} mock_client = mock_get_client.return_value mock_client.list_extensions.return_value = test_ext_list @@ -4357,7 +4366,7 @@ class TestAPI(TestAPIBase): def test_update_instance_vnic_index(self, mock_get_client, mock_refresh_extensions): api = neutronapi.API() - api.extensions = set([constants.VNIC_INDEX_EXT]) + api.extensions = set([constants.VNIC_INDEX]) mock_client = mock_get_client.return_value mock_client.update_port.return_value = 'port' @@ -4382,7 +4391,7 @@ class TestAPI(TestAPIBase): self, get_client_mock ): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) # We pass in a port profile which has a migration attribute and also # a second port profile attribute 'fake_profile' this can be @@ -4426,7 +4435,7 @@ class TestAPI(TestAPIBase): value is None. """ instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) fake_ports = {'ports': [ {'id': uuids.portid, @@ -4602,7 +4611,7 @@ class TestAPI(TestAPIBase): def test_update_port_bindings_for_instance_with_pci_no_migration(self, get_client_mock, get_pci_device_devspec_mock): - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) devspec = mock.Mock() devspec.get_tags.return_value = {'physical_network': 'physnet1'} @@ -4652,7 +4661,7 @@ class TestAPI(TestAPIBase): def test_update_port_bindings_for_instance_with_same_host_failed_vif_type( self, get_client_mock): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) list_ports_mock = mock.Mock() update_port_mock = mock.Mock() @@ -4697,7 +4706,7 @@ class TestAPI(TestAPIBase): def test_update_port_bindings_for_instance_with_diff_host_unbound_vif_type( self, get_client_mock): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) binding_profile = {'fake_profile': 'fake_data', constants.MIGRATING_ATTR: 'my-dest-host'} @@ -4987,7 +4996,7 @@ class TestAPI(TestAPIBase): self, get_client_mock): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) # We test with an instance host and destination_host where the # port will be moving. get_ports = {'ports': [ @@ -5017,7 +5026,7 @@ class TestAPI(TestAPIBase): destination host and the binding:profile is None in the port. """ instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) # We test with an instance host and destination_host where the # port will be moving but with binding:profile set to None. get_ports = { @@ -5048,7 +5057,7 @@ class TestAPI(TestAPIBase): self, get_client_mock): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) port_id = uuids.port_id get_ports = {'ports': [ {'id': port_id, @@ -5068,7 +5077,7 @@ class TestAPI(TestAPIBase): self, get_client_mock): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) get_ports = {'ports': [ {'id': uuids.port_id, constants.BINDING_HOST_ID: instance.host}]} @@ -5104,7 +5113,7 @@ class TestAPI(TestAPIBase): self, get_client_mock): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) migrate_profile = { constants.MIGRATING_ATTR: 'new-host'} # Pass a port with an migration porfile attribute. @@ -5116,8 +5125,9 @@ class TestAPI(TestAPIBase): self.api.list_ports = mock.Mock(return_value=get_ports) mocked_client = get_client_mock.return_value - with mock.patch.object(self.api, 'supports_port_binding_extension', - return_value=True): + with mock.patch.object( + self.api, 'has_port_binding_extension', return_value=True, + ): self.api.setup_networks_on_host(self.context, instance, host='new-host', @@ -5135,7 +5145,7 @@ class TestAPI(TestAPIBase): which is raised through to the caller. """ instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) migrate_profile = { constants.MIGRATING_ATTR: 'new-host'} # Pass a port with an migration porfile attribute. @@ -5153,8 +5163,9 @@ class TestAPI(TestAPIBase): mocked_client = get_client_mock.return_value mocked_client.delete_port_binding.side_effect = NeutronError - with mock.patch.object(self.api, 'supports_port_binding_extension', - return_value=True): + with mock.patch.object( + self.api, 'has_port_binding_extension', return_value=True, + ): ex = self.assertRaises( exception.PortBindingDeletionFailed, self.api.setup_networks_on_host, @@ -5176,7 +5187,7 @@ class TestAPI(TestAPIBase): self, get_client_mock): instance = fake_instance.fake_instance_obj(self.context) - self.api._has_port_binding_extension = mock.Mock(return_value=True) + self.api.has_port_binding_extension = mock.Mock(return_value=True) # Pass a port without any migration porfile attribute. get_ports = {'ports': [ {'id': uuids.port_id, @@ -5184,7 +5195,7 @@ class TestAPI(TestAPIBase): self.api.list_ports = mock.Mock(return_value=get_ports) update_port_mock = mock.Mock() get_client_mock.return_value.update_port = update_port_mock - with mock.patch.object(self.api, 'supports_port_binding_extension', + with mock.patch.object(self.api, 'has_port_binding_extension', return_value=False): self.api.setup_networks_on_host(self.context, instance, @@ -5242,6 +5253,8 @@ class TestAPI(TestAPIBase): def test_unbind_ports_get_client(self, mock_neutron): self._test_unbind_ports_get_client(mock_neutron) + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.network.neutron.API._show_port') def _test_unbind_ports(self, mock_neutron, mock_show): mock_client = mock.Mock() @@ -5284,7 +5297,11 @@ class TestAPI(TestAPIBase): @mock.patch( 'nova.network.neutron.API.has_extended_resource_request_extension', - new=mock.Mock() + new=mock.Mock(return_value=True), + ) + @mock.patch( + 'nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=True), ) @mock.patch('nova.network.neutron.API.get_instance_nw_info') @mock.patch('nova.network.neutron.excutils') @@ -5827,9 +5844,13 @@ class TestAPI(TestAPIBase): mock_nc.list_ports.return_value = {'ports': []} if fip_ext_enabled: - self.api.extensions = [constants.FIP_PORT_DETAILS] + self.api.extensions = { + constants.FIP_PORT_DETAILS: { + 'alias': constants.FIP_PORT_DETAILS, + }, + } else: - self.api.extensions = [] + self.api.extensions = {} fips = self.api.get_floating_ips_by_project(self.context) @@ -5862,6 +5883,8 @@ class TestAPI(TestAPIBase): """Make sure we don't fail for floating IPs without attached ports.""" self._test_get_floating_ips_by_project(False, False) + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=True)) @mock.patch('nova.network.neutron.API._show_port') def test_unbind_ports_reset_dns_name_by_admin(self, mock_show): neutron = mock.Mock() @@ -5872,7 +5895,6 @@ class TestAPI(TestAPIBase): } } port_client = mock.Mock() - self.api.extensions = [constants.DNS_INTEGRATION] ports = [uuids.port_id] mock_show.return_value = {'id': uuids.port} self.api._unbind_ports(self.context, ports, neutron, port_client) @@ -5885,6 +5907,8 @@ class TestAPI(TestAPIBase): uuids.port_id, port_req_body) neutron.update_port.assert_not_called() + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=True)) @mock.patch('nova.network.neutron.API._show_port') def test_unbind_ports_reset_dns_name_by_non_admin(self, mock_show): neutron = mock.Mock() @@ -5895,7 +5919,6 @@ class TestAPI(TestAPIBase): } } port_client = mock.Mock() - self.api.extensions = [constants.DNS_INTEGRATION] ports = [uuids.port_id] mock_show.return_value = {'id': uuids.port} self.api._unbind_ports(self.context, ports, neutron, port_client) @@ -5909,6 +5932,8 @@ class TestAPI(TestAPIBase): neutron.update_port.assert_called_once_with( uuids.port_id, non_admin_port_req_body) + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.network.neutron.API._show_port') def test_unbind_ports_reset_allocation_in_port_binding(self, mock_show): neutron = mock.Mock() @@ -5924,6 +5949,8 @@ class TestAPI(TestAPIBase): port_client.update_port.assert_called_once_with( uuids.port_id, port_req_body) + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.network.neutron.API._show_port') def test_unbind_ports_reset_binding_profile(self, mock_show): neutron = mock.Mock() @@ -5947,6 +5974,8 @@ class TestAPI(TestAPIBase): port_client.update_port.assert_called_once_with( uuids.port_id, port_req_body) + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.network.neutron.API._populate_neutron_extension_values') @mock.patch('nova.network.neutron.API._update_port', # called twice, fails on the 2nd call and triggers the cleanup @@ -6028,6 +6057,8 @@ class TestAPI(TestAPIBase): neutron_client=mock.ANY) mock_log.assert_not_called() + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.network.neutron.API._show_port', side_effect=Exception) @mock.patch.object(neutronapi.LOG, 'exception') @@ -6045,6 +6076,8 @@ class TestAPI(TestAPIBase): 'binding:profile': {}, 'binding:host_id': None}}) self.assertTrue(mock_log.called) + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.network.neutron.API._show_port') @mock.patch.object(neutronapi.LOG, 'exception') def test_unbind_ports_portnotfound(self, mock_log, mock_show): @@ -6061,6 +6094,8 @@ class TestAPI(TestAPIBase): 'binding:profile': {}, 'binding:host_id': None}}) mock_log.assert_not_called() + @mock.patch('nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.network.neutron.API._show_port') @mock.patch.object(neutronapi.LOG, 'exception') def test_unbind_ports_unexpected_error(self, mock_log, mock_show): @@ -6676,7 +6711,7 @@ class TestAPI(TestAPIBase): """Tests that migrate_instance_start exits early if neutron doesn't have the binding-extended API extension. """ - with mock.patch.object(self.api, 'supports_port_binding_extension', + with mock.patch.object(self.api, 'has_port_binding_extension', return_value=False): self.api.migrate_instance_start( self.context, mock.sentinel.instance, {}) @@ -6696,8 +6731,9 @@ class TestAPI(TestAPIBase): migration = objects.Migration( source_compute='source', dest_compute='dest') - with mock.patch.object(self.api, 'supports_port_binding_extension', - return_value=True): + with mock.patch.object( + self.api, 'has_port_binding_extension', return_value=True, + ): self.api.migrate_instance_start( self.context, instance, migration) @@ -6721,8 +6757,9 @@ class TestAPI(TestAPIBase): migration = objects.Migration( source_compute='source', dest_compute='dest') - with mock.patch.object(self.api, 'supports_port_binding_extension', - return_value=True): + with mock.patch.object( + self.api, 'has_port_binding_extension', return_value=True, + ): self.api.migrate_instance_start( self.context, instance, migration) @@ -6748,8 +6785,9 @@ class TestAPI(TestAPIBase): migration = objects.Migration( source_compute='source', dest_compute='dest') - with mock.patch.object(self.api, 'supports_port_binding_extension', - return_value=True): + with mock.patch.object( + self.api, 'has_port_binding_extension', return_value=True, + ): self.api.migrate_instance_start( self.context, instance, migration) @@ -6772,8 +6810,9 @@ class TestAPI(TestAPIBase): migration = objects.Migration( source_compute='source', dest_compute='dest') - with mock.patch.object(self.api, 'supports_port_binding_extension', - return_value=True): + with mock.patch.object( + self.api, 'has_port_binding_extension', return_value=True, + ): self.api.migrate_instance_start( self.context, instance, migration) @@ -6952,7 +6991,7 @@ class TestAPI(TestAPIBase): def test_get_segment_ids_for_network_no_segment_ext(self): with mock.patch.object( - self.api, '_has_segment_extension', return_value=False + self.api, 'has_segment_extension', return_value=False, ): self.assertEqual( [], self.api.get_segment_ids_for_network(self.context, @@ -6965,7 +7004,7 @@ class TestAPI(TestAPIBase): mock_client.return_value = mocked_client mocked_client.list_subnets.return_value = subnets with mock.patch.object( - self.api, '_has_segment_extension', return_value=True + self.api, 'has_segment_extension', return_value=True, ): res = self.api.get_segment_ids_for_network( self.context, uuids.network_id) @@ -6980,7 +7019,7 @@ class TestAPI(TestAPIBase): mock_client.return_value = mocked_client mocked_client.list_subnets.return_value = subnets with mock.patch.object( - self.api, '_has_segment_extension', return_value=True + self.api, 'has_segment_extension', return_value=True, ): res = self.api.get_segment_ids_for_network( self.context, uuids.network_id) @@ -6995,7 +7034,7 @@ class TestAPI(TestAPIBase): mocked_client.list_subnets.side_effect = ( exceptions.NeutronClientException(status_code=404)) with mock.patch.object( - self.api, '_has_segment_extension', return_value=True + self.api, 'has_segment_extension', return_value=True, ): self.assertRaises(exception.InvalidRoutedNetworkConfiguration, self.api.get_segment_ids_for_network, @@ -7003,7 +7042,7 @@ class TestAPI(TestAPIBase): def test_get_segment_id_for_subnet_no_segment_ext(self): with mock.patch.object( - self.api, '_has_segment_extension', return_value=False + self.api, 'has_segment_extension', return_value=False, ): self.assertIsNone( self.api.get_segment_id_for_subnet(self.context, @@ -7016,7 +7055,7 @@ class TestAPI(TestAPIBase): mock_client.return_value = mocked_client mocked_client.show_subnet.return_value = subnet with mock.patch.object( - self.api, '_has_segment_extension', return_value=True + self.api, 'has_segment_extension', return_value=True, ): res = self.api.get_segment_id_for_subnet( self.context, uuids.subnet_id) @@ -7030,7 +7069,7 @@ class TestAPI(TestAPIBase): mock_client.return_value = mocked_client mocked_client.show_subnet.return_value = subnet with mock.patch.object( - self.api, '_has_segment_extension', return_value=True + self.api, 'has_segment_extension', return_value=True, ): self.assertIsNone( self.api.get_segment_id_for_subnet(self.context, @@ -7043,7 +7082,7 @@ class TestAPI(TestAPIBase): mocked_client.show_subnet.side_effect = ( exceptions.NeutronClientException(status_code=404)) with mock.patch.object( - self.api, '_has_segment_extension', return_value=True + self.api, 'has_segment_extension', return_value=True, ): self.assertRaises(exception.InvalidRoutedNetworkConfiguration, self.api.get_segment_id_for_subnet, @@ -7251,9 +7290,9 @@ class TestInstanceHasExtendedResourceRequest(TestAPIBase): self.addCleanup(patcher.stop) self.mock_client = patcher.start().return_value self.extension = { - "extensions": [ + 'extensions': [ { - "name": constants.RESOURCE_REQUEST_GROUPS_EXTENSION, + 'alias': constants.RESOURCE_REQUEST_GROUPS, } ] } @@ -7901,6 +7940,9 @@ class TestAPIPortbinding(TestAPIBase): self.api.delete_port_binding(self.context, port_id, 'fake-host') + @mock.patch( + 'nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=False)) @mock.patch('nova.accelerator.cyborg._CyborgClient.delete_arqs_by_uuid') @mock.patch('nova.network.neutron.get_binding_profile') @mock.patch('nova.network.neutron.API._show_port') @@ -8290,7 +8332,7 @@ class TestAllocateForInstance(test.NoDBTestCase): requested_ports_dict = {uuids.port1: {}, uuids.port2: {}} mock_neutron.list_extensions.return_value = {"extensions": [ - {"name": "asdf"}]} + {"alias": "asdf"}]} port1 = {"port": {"id": uuids.port1, "mac_address": "mac1r"}} port2 = {"port": {"id": uuids.port2, "mac_address": "mac2r"}} mock_admin.update_port.side_effect = [port1, port2] @@ -8372,6 +8414,10 @@ class TestAPINeutronHostnameDNSPortbinding(TestAPIBase): bind_host_id=self.instance.get('host'), requested_networks=requested_networks) + @mock.patch( + 'nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=True), + ) @mock.patch( 'nova.network.neutron.API.has_extended_resource_request_extension', new=mock.Mock(return_value=False) @@ -8385,8 +8431,8 @@ class TestAPINeutronHostnameDNSPortbinding(TestAPIBase): 11, dns_extension=True, bind_host_id=self.instance.get('host')) @mock.patch( - "nova.network.neutron.API._has_dns_extension", - new=mock.Mock(return_value=True) + 'nova.network.neutron.API.has_dns_extension', + new=mock.Mock(return_value=True), ) def test_allocate_for_instance_with_requested_port_with_dns_domain(self): # The port's dns_name attribute should be set by the port update diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 50cb5536ef92..d1e362fef51d 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -10606,7 +10606,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, self.assertEqual(drvr._uri(), testuri) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file') @@ -10645,7 +10645,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, return_value.obj_to_primitive()['nova_object.data']) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file') @@ -10685,7 +10685,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, return_value.obj_to_primitive()['nova_object.data']) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file') @@ -10722,7 +10722,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, return_value.obj_to_primitive()['nova_object.data']) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file', @@ -10754,7 +10754,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, str(result.serial_listen_addr)) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file', @@ -10775,7 +10775,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, self.assertIsNone(result.serial_listen_addr) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file', @@ -10808,7 +10808,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, result.obj_to_primitive()['nova_object.data']) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file', @@ -10827,7 +10827,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, self.assertTrue(result.dst_supports_numa_live_migration) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file', @@ -10844,7 +10844,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, self.assertNotIn('dst_supports_numa_live_migration', result) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file') @@ -10885,7 +10885,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, return_value.obj_to_primitive()['nova_object.data']) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=False)) @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file') @@ -10930,7 +10930,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, compute_info, compute_info, False) @mock.patch( - 'nova.network.neutron.API.supports_port_binding_extension', + 'nova.network.neutron.API.has_port_binding_extension', new=mock.Mock(return_value=True)) @mock.patch.object( libvirt_driver.LibvirtDriver, diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index c8fd7e22ed38..97b9f87aabbe 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -9161,7 +9161,7 @@ class LibvirtDriver(driver.ComputeDriver): # populate it if we are using multiple port bindings. # TODO(stephenfin): Remove once we can do this unconditionally in X or # later - if self._network_api.supports_port_binding_extension(context): + if self._network_api.has_port_binding_extension(context): data.vifs = ( migrate_data_obj.VIFMigrateData.create_skeleton_migrate_vifs( instance.get_network_info()))