def delete_network_function_device(self, device_data, network_handler=None): """ Delete the NFD :param device_data: NFD :type device_data: dict :returns: None -- Both on success and Failure :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if (any(key not in device_data for key in ['service_details', 'mgmt_port_id']) or type(device_data['service_details']) is not dict or any(key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) or type(device_data['mgmt_port_id']) is not dict or any( key not in device_data['mgmt_port_id'] for key in ['id', 'port_classification', 'port_model'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) image_name = self._get_image_name(device_data) if image_name: self._update_vendor_data(device_data, device_data.get('token')) token = self._get_token(device_data.get('token')) if not token: return None if device_data.get('id'): # delete the device instance # # this method will be invoked again # once the device instance deletion is completed try: self.compute_handler_nova.delete_instance( token, self._get_admin_tenant_id(token=token), device_data['id']) except Exception: LOG.error(_LE('Failed to delete %(instance)s instance'), { 'instance': device_data['service_details']['device_type'] }) else: # device instance deletion is done, delete remaining resources try: interfaces = [device_data['mgmt_port_id']] self._delete_interfaces(device_data, interfaces, network_handler=network_handler) except Exception as e: LOG.error( _LE('Failed to delete the management data port(s). ' 'Error: %(error)s'), {'error': e})
def unplug_network_function_device_interfaces(self, device_data, network_handler=None): """ Detach the network interfaces for NFD :param device_data: NFD :type device_data: dict :returns: bool -- False on failure and True on Success :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if (any(key not in device_data for key in ['id', 'service_details', 'ports']) or type(device_data['service_details']) is not dict or any(key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) or any(key not in port for port in device_data['ports'] for key in ['id', 'port_classification', 'port_model'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) token = self._get_token(device_data.get('token')) if not token: return None image_name = self._get_image_name(device_data) provider_metadata = {} if image_name: provider_metadata = (self._update_provider_metadata_fast( token, device_data['tenant_id'], image_name, device_data)) if not provider_metadata: LOG.debug('Failed to get provider metadata for' ' device deletion.') if provider_metadata.get('supports_hotplug') is False: return True with nfp_ctx_mgr.NovaContextManager.new(suppress=(Exception, )) as ncm: for port in device_data['ports']: port_id = self._get_port_from_pt(device_data, port['id']) ncm.retry(self.compute_handler_nova.detach_interface, token, device_data['tenant_id'], device_data['id'], port_id) # Async change self._delete_port(token, port_id) # Async change: Delete stale l2ps try: self._delete_l2ps(token, device_data, network_handler) except Exception: pass return True
def delete_network_function_device(self, device_data, network_handler=None): """ Delete the NFD :param device_data: NFD :type device_data: dict :returns: None -- Both on success and Failure :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if (any(key not in device_data for key in ['service_details', 'mgmt_port_id']) or type(device_data['service_details']) is not dict or any(key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) or type(device_data['mgmt_port_id']) is not dict or any( key not in device_data['mgmt_port_id'] for key in ['id', 'port_classification', 'port_model'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) token = self._get_token(device_data.get('token')) if not token: return None if device_data.get('id'): # delete the device instance # # this method will be invoked again # once the device instance deletion is completed with nfp_ctx_mgr.NovaContextManager.new( suppress=(Exception, )) as ncm: ncm.retry(self.compute_handler_nova.delete_instance, token, device_data['tenant_id'], device_data['id']) else: # device instance deletion is done, delete remaining resources try: interfaces = [device_data['mgmt_port_id']] self._delete_interfaces(device_data, interfaces, network_handler=network_handler) except Exception as e: LOG.error( 'Failed to delete the management data port(s). ' 'Error: %(error)s', {'error': e})
def get_network_function_device_status(self, device_data, ignore_failure=False): """ Get the status of NFD :param device_data: NFD :type device_data: dict :returns: None -- On failure :return: str -- status string :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if ( any(key not in device_data for key in ['id', 'service_details']) or type(device_data['service_details']) is not dict or any(key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) ): raise exceptions.IncompleteData() if ( device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE ): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) token = self._get_token(device_data.get('token')) if not token: return None try: device = self.compute_handler_nova.get_instance( device_data['token'], device_data['tenant_id'], device_data['id']) except Exception: if ignore_failure: return None LOG.error(_LE('Failed to get %(instance)s instance details'), {'instance': device_data['service_details']['device_type']}) return None # TODO(RPM): should we raise an Exception here? return device['status']
def unplug_network_function_device_interfaces(self, device_data, network_handler=None): """ Detach the network interfaces for NFD :param device_data: NFD :type device_data: dict :returns: bool -- False on failure and True on Success :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if (any(key not in device_data for key in ['id', 'service_details', 'ports']) or type(device_data['service_details']) is not dict or any(key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) or any(key not in port for port in device_data['ports'] for key in ['id', 'port_classification', 'port_model'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) image_name = self._get_image_name(device_data) if image_name: self._update_vendor_data(device_data, device_data.get('token')) token = self._get_token(device_data.get('token')) if not token: return None try: for port in device_data['ports']: port_id = network_handler.get_port_id(token, port['id']) self.compute_handler_nova.detach_interface( token, self._get_admin_tenant_id(token=token), device_data['id'], port_id) except Exception as e: LOG.error( _LE('Failed to unplug interface(s) from the device.' 'Error: %(error)s'), {'error': e}) return None else: return True
def _validate_create_nfd_data(self, device_data): if (any(key not in device_data for key in [ 'service_details', 'name', 'management_network_info', 'ports' ]) or type(device_data['service_details']) is not dict or any( key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) or any(key not in device_data['management_network_info'] for key in ['id']) or type(device_data['ports']) is not list or any( key not in port for port in device_data['ports'] for key in ['id', 'port_classification', 'port_model'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type'])
def get_network_function_device_status(self, device_data, ignore_failure=False): """ Get the status of NFD :param device_data: NFD :type device_data: dict :returns: None -- On failure :return: str -- status string :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if (any(key not in device_data for key in ['id', 'service_details']) or type(device_data['service_details']) is not dict or any(key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) token = self._get_token(device_data.get('token')) if not token: return None with nfp_ctx_mgr.NovaContextManager.new(suppress=(Exception, )) as ncm: device = ncm.retry(self.compute_handler_nova.get_instance, device_data['token'], device_data['tenant_id'], device_data['id']) return device['status']
def plug_network_function_device_interfaces(self, device_data, network_handler=None): """ Attach the network interfaces for NFD :param device_data: NFD :type device_data: dict :returns: bool -- False on failure and True on Success :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if (any(key not in device_data for key in ['id', 'service_details', 'ports']) or type(device_data['service_details']) is not dict or any(key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) or type(device_data['ports']) is not list or any( key not in port for port in device_data['ports'] for key in ['id', 'port_classification', 'port_model'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) token = device_data['token'] tenant_id = device_data['tenant_id'] provider_metadata = device_data['provider_metadata'] enable_port_security = device_data.get('enable_port_security') if provider_metadata.get('supports_hotplug') is False: return True try: executor = nfp_executor.TaskExecutor(jobs=10) for port in device_data['ports']: if port['port_classification'] == nfp_constants.PROVIDER: service_type = device_data['service_details'][ 'service_type'].lower() if service_type.lower() in [ nfp_constants.FIREWALL.lower(), nfp_constants.VPN.lower() ]: executor.add_job( 'SET_PROMISCUOS_MODE', network_handler.set_promiscuos_mode_fast, token, port['id'], enable_port_security) executor.add_job( 'ATTACH_INTERFACE', self.compute_handler_nova.attach_interface, token, tenant_id, device_data['id'], port['id']) break executor.fire() for port in device_data['ports']: if port['port_classification'] == nfp_constants.CONSUMER: service_type = device_data['service_details'][ 'service_type'].lower() if service_type.lower() in [ nfp_constants.FIREWALL.lower(), nfp_constants.VPN.lower() ]: executor.add_job( 'SET_PROMISCUOS_MODE', network_handler.set_promiscuos_mode_fast, token, port['id'], enable_port_security) executor.add_job( 'ATTACH_INTERFACE', self.compute_handler_nova.attach_interface, token, tenant_id, device_data['id'], port['id']) break executor.fire() except Exception as e: LOG.error( 'Failed to plug interface(s) to the device.' 'Error: %(error)s', {'error': e}) return None else: return True
def create_network_function_device(self, device_data, network_handler=None): """ Create a NFD :param device_data: NFD data :type device_data: dict :returns: None -- when there is a failure in creating NFD :return: dict -- NFD created :raises: exceptions.IncompleteData, exceptions.ComputePolicyNotSupported """ if (any(key not in device_data for key in [ 'service_details', 'name', 'management_network_info', 'ports' ]) or type(device_data['service_details']) is not dict or any( key not in device_data['service_details'] for key in ['service_vendor', 'device_type', 'network_mode']) or any(key not in device_data['management_network_info'] for key in ['id']) or type(device_data['ports']) is not list or any( key not in port for port in device_data['ports'] for key in ['id', 'port_classification', 'port_model'])): raise exceptions.IncompleteData() if (device_data['service_details']['device_type'] != nfp_constants.NOVA_MODE): raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) token = device_data['token'] admin_tenant_id = device_data['admin_tenant_id'] image_name = self._get_image_name(device_data) executor = nfp_executor.TaskExecutor(jobs=3) image_id_result = {} executor.add_job('UPDATE_VENDOR_DATA', self._update_vendor_data_fast, token, admin_tenant_id, image_name, device_data) executor.add_job('GET_INTERFACES_FOR_DEVICE_CREATE', self._get_interfaces_for_device_create, token, admin_tenant_id, network_handler, device_data) executor.add_job('GET_IMAGE_ID', self.get_image_id, self.compute_handler_nova, token, admin_tenant_id, image_name, result_store=image_id_result) executor.fire() interfaces = device_data.pop('interfaces', None) if not interfaces: LOG.exception(_LE('Failed to get interfaces for device creation.')) return None else: management_interface = interfaces[0] image_id = image_id_result.get('result', None) if not image_id: LOG.error(_LE('Failed to get image id for device creation.')) self._delete_interfaces(device_data, interfaces, network_handler=network_handler) return None if device_data['service_details'].get('flavor'): flavor = device_data['service_details']['flavor'] else: LOG.info( _LI("No Device flavor provided in service profile's " "service flavor field, using default " "flavor: m1.medium")) flavor = 'm1.medium' interfaces_to_attach = [] for interface in interfaces: interfaces_to_attach.append({'port': interface['port_id']}) instance_name = device_data['name'] instance_id_result = {} port_details_result = {} executor.add_job('CREATE_INSTANCE', self.create_instance, self.compute_handler_nova, token, admin_tenant_id, image_id, flavor, interfaces_to_attach, instance_name, result_store=instance_id_result) executor.add_job('GET_NEUTRON_PORT_DETAILS', self.get_neutron_port_details, network_handler, token, management_interface['port_id'], result_store=port_details_result) executor.fire() instance_id = instance_id_result.get('result', None) if not instance_id: LOG.error(_LE('Failed to create %(device_type)s instance.')) self._delete_interfaces(device_data, interfaces, network_handler=network_handler) return None mgmt_ip_address = None mgmt_neutron_port_info = port_details_result.get('result', None) if not mgmt_neutron_port_info: LOG.error(_LE('Failed to get management port details. ')) try: self.compute_handler_nova.delete_instance( token, admin_tenant_id, instance_id) except Exception as e: LOG.error( _LE('Failed to delete %(device_type)s instance.' 'Error: %(error)s'), { 'device_type': (device_data['service_details']['device_type']), 'error': e }) self._delete_interfaces(device_data, interfaces, network_handler=network_handler) return None mgmt_ip_address = mgmt_neutron_port_info['ip_address'] return { 'id': instance_id, 'name': instance_name, 'mgmt_ip_address': mgmt_ip_address, 'mgmt_port_id': interfaces[0], 'mgmt_neutron_port_info': mgmt_neutron_port_info, 'max_interfaces': self.maximum_interfaces, 'interfaces_in_use': len(interfaces_to_attach), 'description': '' } # TODO(RPM): what should be the description