def test_activate_port_binding(self): port, new_binding = self._create_port_and_binding() with mock.patch.object(mechanism_test.TestMechanismDriver, '_check_port_context'): active_binding = self._activate_port_binding(port['id'], self.host, raw_response=False) self._assert_bound_port_binding(active_binding) updated_port = self._show('ports', port['id'])['port'] self.assertEqual(new_binding[pbe_ext.HOST], updated_port[portbindings.HOST_ID]) self.assertEqual(new_binding[pbe_ext.PROFILE], updated_port[portbindings.PROFILE]) self.assertEqual(new_binding[pbe_ext.VNIC_TYPE], updated_port[portbindings.VNIC_TYPE]) self.assertEqual(new_binding[pbe_ext.VIF_TYPE], updated_port[portbindings.VIF_TYPE]) self.assertEqual(new_binding[pbe_ext.VIF_DETAILS], updated_port[portbindings.VIF_DETAILS]) retrieved_bindings = self._list_port_bindings( port['id'], raw_response=False)['bindings'] retrieved_active_binding = utils.get_port_binding_by_status_and_host( retrieved_bindings, const.ACTIVE) self._assert_bound_port_binding(retrieved_active_binding) retrieved_inactive_binding = utils.get_port_binding_by_status_and_host( retrieved_bindings, const.INACTIVE) self._assert_unbound_port_binding(retrieved_inactive_binding)
def test_get_port_binding_by_status_and_host(self): bindings = [] self.assertIsNone( utils.get_port_binding_by_status_and_host(bindings, constants.INACTIVE)) bindings.extend([{ pb_ext.STATUS: constants.INACTIVE, pb_ext.HOST: 'host-1' }, { pb_ext.STATUS: constants.INACTIVE, pb_ext.HOST: 'host-2' }]) self.assertEqual( 'host-1', utils.get_port_binding_by_status_and_host( bindings, constants.INACTIVE)[pb_ext.HOST]) self.assertEqual( 'host-2', utils.get_port_binding_by_status_and_host( bindings, constants.INACTIVE, host='host-2')[pb_ext.HOST]) self.assertIsNone( utils.get_port_binding_by_status_and_host(bindings, constants.ACTIVE)) self.assertRaises(exceptions.PortBindingNotFound, utils.get_port_binding_by_status_and_host, bindings, constants.ACTIVE, 'host', True, 'port_id')
def test_activate_port_binding(self): port, new_binding = self._create_port_and_binding() with mock.patch.object(mechanism_test.TestMechanismDriver, '_check_port_context'): active_binding = self._activate_port_binding( port['id'], self.host, raw_response=False) self._assert_bound_port_binding(active_binding) updated_port = self._show('ports', port['id'])['port'] self.assertEqual(new_binding[pbe_ext.HOST], updated_port[portbindings.HOST_ID]) self.assertEqual(new_binding[pbe_ext.PROFILE], updated_port[portbindings.PROFILE]) self.assertEqual(new_binding[pbe_ext.VNIC_TYPE], updated_port[portbindings.VNIC_TYPE]) self.assertEqual(new_binding[pbe_ext.VIF_TYPE], updated_port[portbindings.VIF_TYPE]) self.assertEqual(new_binding[pbe_ext.VIF_DETAILS], updated_port[portbindings.VIF_DETAILS]) retrieved_bindings = self._list_port_bindings( port['id'], raw_response=False)['bindings'] retrieved_active_binding = utils.get_port_binding_by_status_and_host( retrieved_bindings, const.ACTIVE) self._assert_bound_port_binding(retrieved_active_binding) retrieved_inactive_binding = utils.get_port_binding_by_status_and_host( retrieved_bindings, const.INACTIVE) self._assert_unbound_port_binding(retrieved_inactive_binding)
def test_list_port_bindings(self): port, new_binding = self._create_port_and_binding() retrieved_bindings = self._list_port_bindings( port['id'], raw_response=False)['bindings'] self.assertEqual(2, len(retrieved_bindings)) status = const.ACTIVE self._assert_unbound_port_binding( utils.get_port_binding_by_status_and_host(retrieved_bindings, status)) status = const.INACTIVE self._assert_bound_port_binding( utils.get_port_binding_by_status_and_host(retrieved_bindings, status, host=self.host))
def validate_log_type_for_port(log_type, port): """Validate a specific logging type on a specific port This method checks whether or not existing a log_driver which supports for the logging type on the port. :param log_type: a logging type (e.g security_group) :param port: a port object """ log_plugin = directory.get_plugin(alias=plugin_const.LOG_API) drivers = log_plugin.driver_manager.drivers port_binding = utils.get_port_binding_by_status_and_host( port.bindings, constants.ACTIVE, raise_if_not_found=True, port_id=port['id']) for driver in drivers: vif_type = port_binding.vif_type if vif_type not in SKIPPED_VIF_TYPES: if not _validate_vif_type(driver, vif_type, port['id']): continue else: vnic_type = port_binding.vnic_type if not _validate_vnic_type(driver, vnic_type, port['id']): continue if driver.is_logging_type_supported(log_type): return True return False
def get_device_details(self, context, device, agent_id, host=None, agent_restarted=False): port_obj = self.remote_resource_cache.get_resource_by_id( resources.PORT, device, agent_restarted) if not port_obj: LOG.debug("Device %s does not exist in cache.", device) return {'device': device} if not port_obj.binding_levels: LOG.warning("Device %s is not bound.", port_obj) return {'device': device} segment = port_obj.binding_levels[-1].segment if not segment: LOG.debug("Device %s is not bound to any segment.", port_obj) return {'device': device} binding = utils.get_port_binding_by_status_and_host( port_obj.bindings, constants.ACTIVE, raise_if_not_found=True, port_id=port_obj.id) if (port_obj.device_owner.startswith( constants.DEVICE_OWNER_COMPUTE_PREFIX) and binding[pb_ext.HOST] != host): LOG.debug("Device %s has no active binding in this host", port_obj) return {'device': device, constants.NO_ACTIVE_BINDING: True} net = self.remote_resource_cache.get_resource_by_id( resources.NETWORK, port_obj.network_id) net_qos_policy_id = net.qos_policy_id # match format of old RPC interface mac_addr = str(netaddr.EUI(str(port_obj.mac_address), dialect=netaddr.mac_unix_expanded)) entry = { 'device': device, 'device_id': port_obj.device_id, 'network_id': port_obj.network_id, 'port_id': port_obj.id, 'mac_address': mac_addr, 'admin_state_up': port_obj.admin_state_up, 'network_type': segment.network_type, 'segmentation_id': segment.segmentation_id, 'physical_network': segment.physical_network, 'fixed_ips': [{'subnet_id': o.subnet_id, 'ip_address': str(o.ip_address)} for o in port_obj.fixed_ips], 'device_owner': port_obj.device_owner, 'allowed_address_pairs': [{'mac_address': o.mac_address, 'ip_address': o.ip_address} for o in port_obj.allowed_address_pairs], 'port_security_enabled': getattr(port_obj.security, 'port_security_enabled', True), 'qos_policy_id': port_obj.qos_policy_id, 'network_qos_policy_id': net_qos_policy_id, 'profile': binding.profile, 'vif_type': binding.vif_type, 'vnic_type': binding.vnic_type, 'security_groups': list(port_obj.security_group_ids) } LOG.debug("Returning: %s", entry) return entry
def get_device_details(self, context, device, agent_id, host=None): port_obj = self.remote_resource_cache.get_resource_by_id( resources.PORT, device) if not port_obj: LOG.debug("Device %s does not exist in cache.", device) return {'device': device} if not port_obj.binding_levels: LOG.warning("Device %s is not bound.", port_obj) return {'device': device} segment = port_obj.binding_levels[-1].segment if not segment: LOG.debug("Device %s is not bound to any segment.", port_obj) return {'device': device} binding = utils.get_port_binding_by_status_and_host( port_obj.bindings, constants.ACTIVE, raise_if_not_found=True, port_id=port_obj.id) if (port_obj.device_owner.startswith( constants.DEVICE_OWNER_COMPUTE_PREFIX) and binding[pb_ext.HOST] != host): LOG.debug("Device %s has no active binding in this host", port_obj) return {'device': device, n_const.NO_ACTIVE_BINDING: True} net = self.remote_resource_cache.get_resource_by_id( resources.NETWORK, port_obj.network_id) net_qos_policy_id = net.qos_policy_id # match format of old RPC interface mac_addr = str(netaddr.EUI(str(port_obj.mac_address), dialect=netaddr.mac_unix_expanded)) entry = { 'device': device, 'network_id': port_obj.network_id, 'port_id': port_obj.id, 'mac_address': mac_addr, 'admin_state_up': port_obj.admin_state_up, 'network_type': segment.network_type, 'segmentation_id': segment.segmentation_id, 'physical_network': segment.physical_network, 'fixed_ips': [{'subnet_id': o.subnet_id, 'ip_address': str(o.ip_address)} for o in port_obj.fixed_ips], 'device_owner': port_obj.device_owner, 'allowed_address_pairs': [{'mac_address': o.mac_address, 'ip_address': o.ip_address} for o in port_obj.allowed_address_pairs], 'port_security_enabled': getattr(port_obj.security, 'port_security_enabled', True), 'qos_policy_id': port_obj.qos_policy_id, 'network_qos_policy_id': net_qos_policy_id, 'profile': binding.profile, 'security_groups': list(port_obj.security_group_ids) } LOG.debug("Returning: %s", entry) return entry
def _get_method_host(self, rtype, event, payload): """Constructs the name of method to be called in the legacy interface. If the event received is a port update that contains a binding activation where a previous binding is deactivated, the method name is 'binding_deactivate' and the host where the binding has to be deactivated is returned. Otherwise, the method name is constructed from rtype and the event received and the host is None. """ is_delete = event == callback_events.AFTER_DELETE suffix = 'delete' if is_delete else 'update' method = "%s_%s" % (rtype, suffix) host_with_activation = None host_with_deactivation = None if is_delete or rtype != callback_resources.PORT: return method, host_with_activation, host_with_deactivation # A port update was received. Find out if it is a binding activation # where a previous binding was deactivated BINDINGS = pb_ext.COLLECTION_NAME changed_fields = payload.metadata['changed_fields'] if BINDINGS in changed_fields: existing_active_binding = ( utils.get_port_binding_by_status_and_host( getattr(payload.states[0], 'bindings', []), constants.ACTIVE)) updated_active_binding = ( utils.get_port_binding_by_status_and_host( getattr(payload.latest_state, 'bindings', []), constants.ACTIVE)) if (existing_active_binding and updated_active_binding and existing_active_binding.host != updated_active_binding.host): if (utils.get_port_binding_by_status_and_host( getattr(payload.latest_state, 'bindings', []), constants.INACTIVE, host=existing_active_binding.host)): method = BINDING_DEACTIVATE host_with_activation = updated_active_binding.host host_with_deactivation = existing_active_binding.host return method, host_with_activation, host_with_deactivation
def _get_method_host(self, rtype, event, **kwargs): """Constructs the name of method to be called in the legacy interface. If the event received is a port update that contains a binding activation where a previous binding is deactivated, the method name is 'binding_deactivate' and the host where the binding has to be deactivated is returned. Otherwise, the method name is constructed from rtype and the event received and the host is None. """ is_delete = event == callback_events.AFTER_DELETE suffix = 'delete' if is_delete else 'update' method = "%s_%s" % (rtype, suffix) host_with_activation = None host_with_deactivation = None if is_delete or rtype != callback_resources.PORT: return method, host_with_activation, host_with_deactivation # A port update was received. Find out if it is a binding activation # where a previous binding was deactivated BINDINGS = pb_ext.COLLECTION_NAME if BINDINGS in kwargs.get('changed_fields', set()): existing_active_binding = ( utils.get_port_binding_by_status_and_host( getattr(kwargs['existing'], 'bindings', []), constants.ACTIVE)) updated_active_binding = ( utils.get_port_binding_by_status_and_host( getattr(kwargs['updated'], 'bindings', []), constants.ACTIVE)) if (existing_active_binding and updated_active_binding and existing_active_binding.host != updated_active_binding.host): if (utils.get_port_binding_by_status_and_host( getattr(kwargs['updated'], 'bindings', []), constants.INACTIVE, host=existing_active_binding.host)): method = BINDING_DEACTIVATE host_with_activation = updated_active_binding.host host_with_deactivation = existing_active_binding.host return method, host_with_activation, host_with_deactivation
def _extend_port_portbinding(port_res, port_db): plugin = directory.get_plugin() plugin.extend_port_dict_binding(port_res, port_db) if port_db.nsx_port_attributes: port_res[pbin.VNIC_TYPE] = port_db.nsx_port_attributes.vnic_type if hasattr(port_db, 'port_bindings'): binding = p_utils.get_port_binding_by_status_and_host( port_db.port_bindings, constants.ACTIVE) if binding: plugin.extend_port_portbinding(port_res, binding)
def update_port_precommit(self, context): # This mech doesn't check whether port is binded to VM so # the mech treats all ports as VM's port plugin = directory.get_plugin() port_id = context.current["id"] port_db = plugin._get_port(context._plugin_context, port_id) cur_binding = utils.get_port_binding_by_status_and_host( port_db.port_bindings, constants.ACTIVE) agents = context.host_agents(self.agent_type) network_id = port_db.network_id node_id = None if agents: # SR plugin expects to return just one sr_agent agent = agents[0] if agent["alive"]: node_id = agent["configurations"].get("segment_node_id") if self._is_required_to_update_binding_profile(context, node_id): # Specify vrf name network = plugin.get_network(context._plugin_context, network_id) network_type = network["provider:network_type"] project_id = port_db.project_id vrf = vrf_utils.get_vrf_name(network_type, project_id, network_id) if not vrf: return # Prepare vrf port info vrf_ports = plugin.get_ports(context._plugin_context, filters={'name': [vrf]}) if not vrf_ports: vrf_port = self._create_vrf_ip(context._plugin_context, vrf) else: vrf_port = vrf_ports[0] vrf_ip = vrf_port['fixed_ips'][0]['ip_address'] subnet = plugin.get_subnet(context._plugin_context, vrf_port['fixed_ips'][0]['subnet_id']) cidr = subnet['cidr'] # update DB cur_binding.profile = jsonutils.dumps({ "segment_node_id": node_id, "vrf": vrf, "vrf_ip": vrf_ip, "vrf_cidr": cidr }) if context.host == context.original_host: return self._insert_provisioning_block(context)
def validate_rule_for_port(self, rule, port): port_binding = utils.get_port_binding_by_status_and_host( port.bindings, lib_constants.ACTIVE, raise_if_not_found=True, port_id=port['id']) for driver in self._drivers: vif_type = port_binding.vif_type if vif_type not in SKIPPED_VIF_TYPES: if not self._validate_vif_type(driver, vif_type, port['id']): continue else: vnic_type = port_binding.vnic_type if not self._validate_vnic_type(driver, vnic_type, port['id']): continue if driver.is_rule_supported(rule): return True return False
def validate_rule_for_port(self, context, rule, port): validated = super(NuageQosDriver, self).validate_rule_for_port( context, rule, port) if not validated: return False # This driver only supports DIRECT VNIC type with switchdev # capabilities, not SRIOV. port_binding = utils.get_port_binding_by_status_and_host( port.bindings, constants.ACTIVE, raise_if_not_found=True, port_id=port['id']) vnic_type = port_binding.vnic_type if vnic_type == portbindings.VNIC_DIRECT: # Reject when there are no switchdev capabilities profile = port_binding.get('profile') capabilities = profile.get('capabilities', []) if profile else [] return 'switchdev' in capabilities else: return True