def post_subscription(body): """ Creates a subscription Args: body (dict): subscription request body to save. Returns: Success : NoContent, 201 Invalid Data : Invalid message, 400 Duplicate Data : Duplicate field detail, 409 Raises: Error: If anything fails in the server. """ response = NoContent, HTTPStatus.CREATED.value try: subscription_service.create_subscription(body['subscription']) except DuplicateDataException as e: logger.error( f'Failed to create subscription for ' f'{body["subscription"]["subscriptionName"]} due to duplicate data: {e}', exc_info=True) response = e.args[0], HTTPStatus.CONFLICT.value except InvalidDataException as e: logger.error( f'Failed to create subscription for ' f'{body["subscription"]["subscriptionName"]} due to invalid data: {e}', exc_info=True) response = e.args[0], HTTPStatus.BAD_REQUEST.value return response
def filter_nf_to_meas_grp(nf_name, measurement_group_name, status): """ Performs successful status update for a nf under filter update request for a particular subscription and measurement group Args: nf_name (string): The network function name measurement_group_name (string): Measurement group name status (string): status of the network function for measurement group """ try: if status == MgNfState.DELETED.value: delete_nf_to_measurement_group(nf_name, measurement_group_name, MgNfState.DELETED.value) elif status == MgNfState.CREATED.value: update_measurement_group_nf_status(measurement_group_name, MgNfState.CREATED.value, nf_name) nf_measurement_group_rels = NfMeasureGroupRelationalModel.query.filter( NfMeasureGroupRelationalModel.measurement_grp_name == measurement_group_name, or_( NfMeasureGroupRelationalModel.nf_measure_grp_status.like( 'PENDING_%'), NfMeasureGroupRelationalModel.nf_measure_grp_status.like( '%_FAILED'))).all() if not nf_measurement_group_rels: MeasurementGroupModel.query.filter( MeasurementGroupModel.measurement_group_name == measurement_group_name). \ update({MeasurementGroupModel.administrative_state: AdministrativeState. UNLOCKED.value}, synchronize_session='evaluate') db.session.commit() except Exception as e: logger.error( 'Failed update filter response for measurement group name: ' f'{measurement_group_name}, nf name: {nf_name} due to: {e}')
def poll_policy_topic(self): """ This method polls MR for response from policy. It checks whether the message is for the relevant subscription and then handles the response """ self.app.app_context().push() logger.info( 'Polling MR for XNF activation/deactivation policy response events.' ) try: response_data = AppConfig.get_instance(). \ get_from_topic(MRTopic.POLICY_PM_SUBSCRIBER.value, 'dcae_pmsh_policy_cl_input') for data in response_data: data = json.loads(data) measurement_group_name = data['status']['measurementGroupName'] subscription_name = data['status']['subscriptionName'] measurement_group = (MeasurementGroupModel.query.filter( MeasurementGroupModel.measurement_group_name == measurement_group_name, subscription_name == MeasurementGroupModel.subscription_name).one_or_none()) nf_name = data['status']['nfName'] response_message = data['status']['message'] if measurement_group: self._handle_response( measurement_group_name, measurement_group.administrative_state, nf_name, response_message) else: logger.info( f'Polled MR response provides missing measurement ' f'group name : {measurement_group_name}') except Exception as err: logger.error( f'Error trying to poll policy response topic on MR: {err}', exc_info=True)
def get_from_topic(self, mr_topic, consumer_id, consumer_group='dcae_pmsh_cg', timeout=5000, **kwargs): """ Returns the json data from the MrTopic. Args: mr_topic (enum) : Message Router topic to subscribe. consumer_id (str): Within your subscribers group, a name that uniquely identifies your subscribers process. consumer_group (str): A name that uniquely identifies your subscribers. timeout (int): The request timeout value in mSec. Returns: list[str]: the json response from DMaaP Message Router topic. """ try: session = requests.Session() topic_url = self.streams_subscribes[mr_topic].get('dmaap_info').get('topic_url') headers = {'accept': 'application/json', 'content-type': 'application/json', 'InvocationID': kwargs['invocation_id'], 'RequestID': kwargs['request_id']} logger.info(f'Fetching messages from MR topic: {topic_url}') response = session.get(f'{topic_url}/{consumer_group}/{consumer_id}' f'?timeout={timeout}', auth=HTTPBasicAuth(self.aaf_id, self.aaf_pass), headers=headers, verify=(self.ca_cert_path if self.enable_tls else False)) if response.status_code == 503: logger.error(f'MR Service is unavailable at present: {response.content}') response.raise_for_status() if response.ok: return response.json() except Exception as e: logger.error(f'Failed to fetch message from MR: {e}', exc_info=True) raise
def _filter_nf_data(nf_data, app_conf, nf_filter): """ Returns a list of filtered NetworkFunctions using the nf_filter. Args: nf_data (dict): the nf json data from AAI. app_conf (AppConfig): the AppConfig object. nf_filter (NetworkFunctionFilter): filter data to apply on network functions Returns: NetworkFunction (list): a list of filtered NetworkFunction Objects. Raises: KeyError: if AAI data cannot be parsed. """ nf_list = [] try: for nf in nf_data['results']: if nf['properties'].get('orchestration-status') != 'Active': continue name_identifier = 'pnf-name' if nf['node-type'] == 'pnf' else 'vnf-name' new_nf = mod.network_function.NetworkFunction( nf_name=nf['properties'].get(name_identifier), ipv4_address=nf['properties'].get('ipaddress-v4-oam'), ipv6_address=nf['properties'].get('ipaddress-v6-oam'), model_invariant_id=nf['properties'].get('model-invariant-id'), model_version_id=nf['properties'].get('model-version-id')) if not new_nf.set_nf_model_params(app_conf): continue if nf_filter.is_nf_in_filter(new_nf): nf_list.append(new_nf) except KeyError as e: logger.error(f'Failed to parse AAI data: {e}', exc_info=True) raise return nf_list
def add_new_filtered_nfs(filtered_nfs, unlocked_mgs, sub_model): """ Inserts the filtered nfs in measurement groups of subscription Args: filtered_nfs (List[NetworkFunction]): nfs to be inserted unlocked_mgs (List[MeasurementGroupModel]): mgs to be updated with new nfs sub_model (SubscriptionModel): subscription model to update """ if filtered_nfs: logger.info(f'Applying the filtered nfs for subscription: ' f'{sub_model.subscription_name}') save_filtered_nfs(filtered_nfs) apply_subscription_to_nfs(filtered_nfs, sub_model.subscription_name) db.session.commit() if unlocked_mgs: apply_measurement_grp_to_nfs(filtered_nfs, unlocked_mgs) db.session.commit() publish_measurement_grp_to_nfs(sub_model, filtered_nfs, unlocked_mgs) else: logger.error(f'All measurement groups are locked for subscription: ' f'{sub_model.subscription_name}, ' f'please verify/check measurement groups.') else: logger.error(f'No network functions found for subscription: ' f'{sub_model.subscription_name}, ' f'please verify/check NetworkFunctionFilter.')
def main(): try: try: app = create_app() app.app_context().push() db.create_all(app=app) pmsh_app_conf = AppConfig() except Exception as e: logger.error(f'Failed to get config and create application: {e}', exc_info=True) sys.exit(e) policy_response_handler = PolicyResponseHandler(app) policy_response_handler_thread = PeriodicTask( 25, policy_response_handler.poll_policy_topic) policy_response_handler_thread.name = 'policy_event_thread' logger.info('Start polling PMSH_CL_INPUT topic on DMaaP MR.') policy_response_handler_thread.start() aai_event_handler = AAIEventHandler(app) aai_event_handler_thread = PeriodicTask(20, aai_event_handler.execute) aai_event_handler_thread.name = 'aai_event_thread' aai_event_handler_thread.start() periodic_tasks = [ policy_response_handler_thread, aai_event_handler_thread ] signal(SIGTERM, ExitHandler(periodic_tasks=periodic_tasks)) launch_api_server(pmsh_app_conf) except Exception as e: logger.error(f'Failed to initialise PMSH: {e}', exc_info=True) sys.exit(e)
def deactivate_nfs(sub_model, measurement_group, nf_meas_relations): """ Deactivates network functions associated with measurement group Args: sub_model (SubscriptionModel): Subscription model measurement_group (MeasurementGroupModel): Measurement group to update nf_meas_relations (list[NfMeasureGroupRelationalModel]): nf to measurement grp relations """ for nf in nf_meas_relations: logger.info( f'Saving measurement group to nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name} with DELETE request') update_measurement_group_nf_status( measurement_group.measurement_group_name, MgNfState.PENDING_DELETE.value, nf.nf_name) try: network_function = NetworkFunction(**nf.serialize_meas_group_nfs()) logger.info( f'Publishing event for nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name} with DELETE request' ) publish_measurement_group(sub_model, measurement_group, network_function, 'DELETE') except Exception as ex: logger.error( f'Publish event failed for nf name, measure_grp_name, sub_name: ' f'{nf.nf_name},{measurement_group.measurement_group_name}, ' f'{sub_model.subscription_name} with error: {ex}')
def run(self): self.function(*self.args, **self.kwargs) while not self.finished.wait(self.interval): try: self.function(*self.args, **self.kwargs) except Exception as e: logger.error(f'Exception in thread: {self.name}: {e}', exc_info=True)
def increment_retry_count(self): try: NetworkFunctionModel.query.filter( NetworkFunctionModel.nf_name == self.nf_name)\ .update({'retry_count': NetworkFunctionModel.retry_count + 1}, synchronize_session='evaluate') db.session.commit() except Exception as e: logger.error( f'Failed to update retry_count of NetworkFunction: {self.nf_name}: {e}', exc_info=True) finally: db.session.remove()
def execute(self): """ Processes AAI UPDATE events for each filtered xNFs where orchestration status is set to Active. """ self.app.app_context().push() logger.info('Polling MR for XNF AAI events.') try: aai_events = AppConfig.get_instance().get_from_topic( MRTopic.AAI_SUBSCRIBER.value, 'dcae_pmsh_aai_event') if aai_events is not None and len(aai_events) != 0: pmsh_nf_names = list(nf.nf_name for nf in NetworkFunction.get_all()) aai_events = [json.loads(e) for e in aai_events] xnf_events = [ e for e in aai_events if is_pnf_xnf(e['event-header']['entity-type']) ] new_nfs = [] for entry in xnf_events: logger.debug(f'AAI-EVENT entry: {entry}') aai_entity = entry['entity'] action = entry['event-header']['action'] entity_type = entry['event-header']['entity-type'] xnf_name = aai_entity['pnf-name'] if entity_type == XNFType.PNF.value \ else aai_entity['vnf-name'] if aai_entity['orchestration-status'] != 'Active': logger.info( f'Skipping XNF {xnf_name} as its orchestration-status ' f'is not "Active"') continue nf = NetworkFunction( nf_name=xnf_name, ipv4_address=aai_entity['ipaddress-v4-oam'], ipv6_address=aai_entity['ipaddress-v6-oam'], model_invariant_id=aai_entity['model-invariant-id'], model_version_id=aai_entity['model-version-id']) if action == AAIEvent.DELETE.value and xnf_name in pmsh_nf_names: logger.info( f'Delete event found for network function {nf.nf_name}' ) NetworkFunction.delete(nf_name=nf.nf_name) logger.info(f'{nf.nf_name} successfully deleted.') elif action == AAIEvent.UPDATE.value and \ xnf_name not in pmsh_nf_names and \ nf.set_nf_model_params(AppConfig.get_instance()): new_nfs.append(nf) if new_nfs: self.apply_nfs_to_subscriptions(new_nfs) except Exception as e: logger.error(f'Failed to process AAI event due to: {e}')
def _get_aai_service_url(): """ Returns the URL of the AAI kubernetes service. Returns: str: the AAI k8s service URL. Raises: KeyError: if AAI env var not found. """ try: aai_ssl_port = environ['AAI_SERVICE_PORT'] return f'https://aai:{aai_ssl_port}/aai/v21' except KeyError as e: logger.error(f'Failed to get AAI env var: {e}', exc_info=True) raise
def _get_config(self): """ Retrieves PMSH's configuration from Config binding service. If a non-2xx response is received, it retries after 2 seconds for 5 times before raising an exception. Returns: dict: Dictionary representation of the the service configuration Raises: Exception: If any error occurred pulling configuration from Config binding service. """ try: logger.info('Attempting to fetch PMSH Configuration from CBS.') config = get_all() logger.info(f'Successfully fetched PMSH config from CBS: {config}') return config except Exception as e: logger.error(f'Failed to get config from CBS: {e}', exc_info=True) raise ValueError(e) from e
def get_subscriptions(): """ Retrieves all the subscriptions that are defined in PMSH. Returns: list (dict), HTTPStatus: All subs in PMSH, 200 dict, HTTPStatus: Exception details of failure, 500 """ logger.info('API call received to fetch all subscriptions') try: subscriptions = subscription_service.get_subscriptions_list() return subscriptions, HTTPStatus.OK.value except Exception as exception: logger.error( f'The following exception occurred while fetching subscriptions: {exception}' ) return { 'error': 'Request was not processed due to Exception : ' f'{exception}' }, HTTPStatus.INTERNAL_SERVER_ERROR.value
def activate_nfs(sub_model, measurement_group): """ Activates network functions associated with measurement group Args: sub_model (SubscriptionModel): Subscription model measurement_group (MeasurementGroupModel): Measurement group to update """ new_nfs = [] sub_nf_names = [nf.nf_name for nf in sub_model.nfs] filtered_nfs = nf_service.capture_filtered_nfs(sub_model.subscription_name) for nf in filtered_nfs: if nf.nf_name not in sub_nf_names: new_nfs.append(nf) if new_nfs: logger.info(f'Adding new nfs to the subscription: ' f'{sub_model.subscription_name}') subscription_service.save_filtered_nfs(new_nfs) subscription_service.apply_subscription_to_nfs( new_nfs, sub_model.subscription_name) for nf in filtered_nfs: logger.info( f'Saving measurement group to nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name} with CREATE request') apply_nf_status_to_measurement_group( nf.nf_name, measurement_group.measurement_group_name, MgNfState.PENDING_CREATE.value) db.session.commit() try: network_function = NetworkFunction(**nf.serialize_nf()) logger.info( f'Publishing event for nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name} with CREATE request' ) publish_measurement_group(sub_model, measurement_group, network_function, 'CREATE') except Exception as ex: logger.error( f'Publish event failed for nf name, measure_grp_name, sub_name: ' f'{nf.nf_name},{measurement_group.measurement_group_name}, ' f'{sub_model.subscription_name} with error: {ex}')
def get_meas_group_with_nfs(subscription_name, measurement_group_name): """ Retrieves the measurement group and it's associated network functions Args: subscription_name (String): Name of the subscription. measurement_group_name (String): Name of the measurement group Returns: dict, HTTPStatus: measurement group info with associated nfs, 200 dict, HTTPStatus: measurement group was not defined, 404 dict, HTTPStatus: Exception details of failure, 500 """ logger.info( 'API call received to query measurement group and associated network' f' functions by using sub name: {subscription_name} and measurement ' f'group name: {measurement_group_name}') try: meas_group = measurement_group_service.query_meas_group_by_name( subscription_name, measurement_group_name) if meas_group is not None: return meas_group.meas_group_with_nfs(), HTTPStatus.OK.value else: logger.error( 'measurement group was not defined with the sub name: ' f'{subscription_name} and meas group name: ' f'{measurement_group_name}') return { 'error': 'measurement group was not defined with the sub name: ' f'{subscription_name} and meas group name: ' f'{measurement_group_name}' }, HTTPStatus.NOT_FOUND.value except Exception as exception: logger.error( 'The following exception occurred while fetching measurement group: ' f'{exception}') return { 'error': 'Request was not processed due to Exception : ' f'{exception}' }, HTTPStatus.INTERNAL_SERVER_ERROR.value
def __call__(self, sig_num, frame): logger.info('Graceful shutdown of PMSH initiated.') logger.debug(f'ExitHandler was called with signal number: {sig_num}.') try: subscriptions_all = subscription_service.query_all_subscriptions() for subscription in subscriptions_all: for mg in subscription.measurement_groups: if mg.administrative_state == AdministrativeState.UNLOCKED.value: measurement_group_service.\ update_admin_status(mg, AdministrativeState.LOCKED.value) except Exception as e: logger.error(f'Failed to shut down PMSH application: {e}', exc_info=True) for thread in self.periodic_tasks: logger.info(f'Cancelling thread {thread.name}') thread.cancel() logger.info('Closing all DB connections') db.session.bind.dispose() db.session.close() db.engine.dispose() ExitHandler.shutdown_signal_received = True
def publish_measurement_grp_to_nfs(sub_model, filtered_nfs, measurement_groups): """ Publishes an event for measurement groups against nfs Args: sub_model(SubscriptionModel): Subscription model object filtered_nfs (list[NetworkFunction])): list of filtered network functions measurement_groups (list[MeasurementGroupModel]): list of unlocked measurement group """ for measurement_group in measurement_groups: for nf in filtered_nfs: try: logger.info(f'Publishing event for nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name}') measurement_group_service.publish_measurement_group( sub_model, measurement_group, nf, 'CREATE') except Exception as ex: logger.error(f'Publish event failed for nf name, measure_grp_name, sub_name: ' f'{nf.nf_name},{measurement_group.measurement_group_name}, ' f'{sub_model.subscription_name} with error: {ex}')
def put_nf_filter(subscription_name, body): """ Performs network function filter update for the respective subscription Args: subscription_name (String): Name of the subscription. body (dict): Request body with nf filter data to update. Returns: string, HTTPStatus: Successfully updated network function Filter, 200 string, HTTPStatus: Invalid request details, 400 string, HTTPStatus: Cannot update as Locked/Filtering request is in progress, 409 string, HTTPStatus: Exception details of server failure, 500 """ logger.info('Performing network function filter update for subscription ' f'with sub name: {subscription_name} ') response = 'Successfully updated network function Filter', HTTPStatus.OK.value try: subscription_service.update_filter(subscription_name, body) except InvalidDataException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.BAD_REQUEST.value except DataConflictException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.CONFLICT.value except Exception as exception: logger.error( 'Update nf filter request was not processed for sub name: ' f'{subscription_name} due to Exception : {exception}') response = 'Update nf filter request was not processed for sub name: ' \ f'{subscription_name} due to Exception : {exception}', \ HTTPStatus.INTERNAL_SERVER_ERROR return response
def update_measurement_group_nf_status(measurement_group_name, status, nf_name): """ Updates the status of a measurement grp for a particular nf Args: measurement_group_name (string): Measurement group name nf_name (string): The network function name status (string): status of the network function for measurement group """ try: logger.info( f'Performing update for measurement group name: {measurement_group_name},' f' network function name: {nf_name} on status: {status}') NfMeasureGroupRelationalModel.query.filter( NfMeasureGroupRelationalModel.measurement_grp_name == measurement_group_name, NfMeasureGroupRelationalModel.nf_name == nf_name). \ update({NfMeasureGroupRelationalModel.nf_measure_grp_status: status}, synchronize_session='evaluate') db.session.commit() except Exception as e: logger.error(f'Failed to update nf: {nf_name} for measurement group: ' f'{measurement_group_name} due to: {e}')
def delete_nf_to_measurement_group(nf_name, measurement_group_name, status): """ Deletes a particular nf related to a measurement group name and if no more relations of nf exist to measurement group then delete nf from PMSH Args: nf_name (string): The network function name measurement_group_name (string): Measurement group name status (string): status of the network function for measurement group """ try: logger.info( f'Performing delete for measurement group name: {measurement_group_name},' f' network function name: {nf_name} on status: {status}') nf_measurement_group_rel = NfMeasureGroupRelationalModel.query.filter( NfMeasureGroupRelationalModel.measurement_grp_name == measurement_group_name, NfMeasureGroupRelationalModel.nf_name == nf_name).one_or_none() db.session.delete(nf_measurement_group_rel) db.session.commit() except Exception as e: logger.error(f'Failed to delete nf: {nf_name} for measurement group: ' f'{measurement_group_name} due to: {e}')
def get_subscription_by_name(subscription_name): """ Retrieves subscription based on the name Args: subscription_name (String): Name of the subscription. Returns: dict, HTTPStatus: single Sub in PMSH, 200 dict, HTTPStatus: subscription not defined, 404 dict, HTTPStatus: Exception details of failure, 500 """ logger.info('API call received to fetch subscription by name') try: subscription = subscription_service.query_subscription_by_name( subscription_name) if subscription is not None: logger.info( f'queried subscription was successful with the name: {subscription_name}' ) return subscription.serialize(), HTTPStatus.OK.value else: logger.error( 'queried subscription was un successful with the name: ' f'{subscription_name}') return { 'error': 'Subscription was not defined with the name : ' f'{subscription_name}' }, HTTPStatus.NOT_FOUND.value except Exception as exception: logger.error( f'While querying the subscription with name: {subscription_name}, ' f'it occurred the following exception "{exception}"') return { 'error': 'Request was not processed due to Exception : ' f'{exception}' }, HTTPStatus.INTERNAL_SERVER_ERROR.value
def apply_nfs_to_subscriptions(new_nfs): """ Applies measurement groups to network functions identified by AAI event Args: new_nfs (list[NetworkFunction]): new network functions identified """ subscriptions = db.session.query(SubscriptionModel).all() if subscriptions: for subscription in subscriptions: try: nf_filter = NetworkFunctionFilter( **subscription.network_filter.serialize()) filtered_nfs = [] for nf in new_nfs: if nf_filter.is_nf_in_filter(nf): filtered_nfs.append(nf) if filtered_nfs: subscription_service.save_filtered_nfs(filtered_nfs) subscription_service. \ apply_subscription_to_nfs(filtered_nfs, subscription.subscription_name) unlocked_meas_grp = subscription_service. \ apply_measurement_grp_to_nfs(filtered_nfs, subscription.measurement_groups) if unlocked_meas_grp: subscription_service. \ publish_measurement_grp_to_nfs(subscription, filtered_nfs, unlocked_meas_grp) else: logger.error( f'All measurement groups are locked for subscription: ' f'{subscription.subscription_name}, ' f'please verify/check measurement groups.') db.session.commit() except Exception as e: logger.error( f'Failed to process AAI event for subscription: ' f'{subscription.subscription_name} due to: {e}') db.session.remove()
def lock_nf_to_meas_grp(nf_name, measurement_group_name, status): """ Deletes a particular nf related to a measurement group name and if no more relations of nf exist to measurement group then delete nf from PMSH Args: nf_name (string): The network function name measurement_group_name (string): Measurement group name status (string): status of the network function for measurement group """ try: delete_nf_to_measurement_group(nf_name, measurement_group_name, status) nf_measurement_group_rels = NfMeasureGroupRelationalModel.query.filter( NfMeasureGroupRelationalModel.measurement_grp_name == measurement_group_name).all() if not nf_measurement_group_rels: MeasurementGroupModel.query.filter( MeasurementGroupModel.measurement_group_name == measurement_group_name). \ update({MeasurementGroupModel.administrative_state: AdministrativeState. LOCKED.value}, synchronize_session='evaluate') db.session.commit() except Exception as e: logger.error('Failed update LOCKED status for measurement group name: ' f'{measurement_group_name} due to: {e}')
def _handle_response(measurement_group_name, administrative_state, nf_name, response_message): """ Handles the response from Policy, updating the DB Args: measurement_group_name (string): The measurement group name administrative_state (string): The administrative state of the measurement group nf_name (string): The network function name response_message (string): The message in the response regarding the state (success|failed) """ logger.info( f'Response from MR: measurement group name: {measurement_group_name} for ' f'NF: {nf_name} received, updating the DB') try: if administrative_state == AdministrativeState.FILTERING.value: nf_msg_rel = NfMeasureGroupRelationalModel.query.filter( NfMeasureGroupRelationalModel.measurement_grp_name == measurement_group_name, NfMeasureGroupRelationalModel.nf_name == nf_name).one_or_none() if nf_msg_rel.nf_measure_grp_status == MgNfState.PENDING_DELETE.value: administrative_state = AdministrativeState.LOCKING.value elif nf_msg_rel.nf_measure_grp_status == MgNfState.PENDING_CREATE.value: administrative_state = AdministrativeState.UNLOCKED.value nf_measure_grp_status = ( mg_nf_states[administrative_state][response_message]).value policy_response_handle_functions[administrative_state][ response_message]( measurement_group_name=measurement_group_name, status=nf_measure_grp_status, nf_name=nf_name) except Exception as err: logger.error(f'Error changing nf_sub status in the DB: {err}') raise
def _get_all_aai_nf_data(app_conf): """ Return queried nf data from the AAI service. Args: app_conf (AppConfig): the AppConfig object. Returns: dict: the json response from AAI query, else None. """ nf_data = None try: session = requests.Session() aai_named_query_endpoint = f'{_get_aai_service_url()}{"/query"}' logger.info('Fetching XNFs from AAI.') headers = _get_aai_request_headers() data = """ {'start': ['network/pnfs', 'network/generic-vnfs'] }""" params = {'format': 'simple', 'nodesOnly': 'true'} response = session.put(aai_named_query_endpoint, headers=headers, auth=HTTPBasicAuth(app_conf.aaf_id, app_conf.aaf_pass), data=data, params=params, verify=(app_conf.ca_cert_path if app_conf.enable_tls else False), cert=((app_conf.cert_path, app_conf.key_path) if app_conf.enable_tls else None)) response.raise_for_status() if response.ok: nf_data = json.loads(response.text) logger.info('Successfully fetched XNFs from AAI') logger.debug(f'XNFs from AAI: {nf_data}') except Exception as e: logger.error(f'Failed to get XNFs from AAI: {e}', exc_info=True) return nf_data
def set_nf_model_params(self, app_conf): params_set = True try: from mod.aai_client import get_aai_model_data sdnc_model_data = get_aai_model_data(app_conf, self.model_invariant_id, self.model_version_id, self.nf_name) try: self.sdnc_model_name = sdnc_model_data['sdnc-model-name'] self.sdnc_model_version = sdnc_model_data['sdnc-model-version'] self.model_name = sdnc_model_data['model-name'] return params_set except KeyError as e: logger.info( f'Skipping NF {self.nf_name} as there is no ' f'sdnc-model data associated in AAI: {e}', exc_info=True) except Exception as e: logger.error( f'Failed to get sdnc-model info for XNF {self.nf_name} from AAI: {e}', exc_info=True) return not params_set
def delete_meas_group_by_name(subscription_name, measurement_group_name): """Deletes the measurement group by name Args: subscription_name (String): Name of the subscription measurement_group_name (String): Name of measurement group Returns: NoneType, HTTPStatus: None, 204 dict, HTTPStatus: measurement group not defined, 404 dict, HTTPStatus: Reason for not deleting measurement group, 409 dict, HTTPStatus: Exception details of failure, 500 """ logger.info( f'API call received to delete measurement group: {measurement_group_name}' ) try: measurement_group_administrative_status = \ measurement_group_service.query_get_meas_group_admin_status(subscription_name, measurement_group_name) if measurement_group_administrative_status == \ measurement_group_service.AdministrativeState.LOCKED.value: if measurement_group_service.query_to_delete_meas_group( subscription_name, measurement_group_name) == 1: return None, HTTPStatus.NO_CONTENT else: logger.error( f'Measurement Group not found with name {measurement_group_name}' ) return { 'error': f'Measurement Group not found with name ' f'{measurement_group_name}' }, HTTPStatus.NOT_FOUND.value else: logger.error( 'Measurement Group was not deleted because the Administrative State ' f'was {measurement_group_administrative_status}') return {'error': 'Measurement Group was not deleted because the Administrative State ' 'was {measurement_group_administrative_status}'}, \ HTTPStatus.CONFLICT.value except Exception as e: logger.error( f'Try again, measurement group {measurement_group_name} was not' f'deleted due to exception: {e}') return { 'error': f'Try again, measurement group {measurement_group_name} was not ' f'deleted due to exception: {e}' }, HTTPStatus.INTERNAL_SERVER_ERROR.value
def delete_subscription_by_name(subscription_name): """ Deletes the subscription by name Args: subscription_name (String): Name of the subscription Returns: NoneType, HTTPStatus: None, 204 dict, HTTPStatus: subscription not defined, 404 dict, HTTPStatus: Reason for not deleting subscription, 409 dict, HTTPStatus: Exception details of failure, 500 """ logger.info( f'API call received to delete subscription by name: {subscription_name}' ) try: unlocked_locking_mgs = \ subscription_service.query_unlocked_mg_by_sub_name(subscription_name) if not unlocked_locking_mgs: if subscription_service.query_to_delete_subscription_by_name( subscription_name) == 1: return None, HTTPStatus.NO_CONTENT else: logger.error( f'Subscription is not defined with name {subscription_name}' ) return {'error': f'Subscription is not defined with name {subscription_name}'}, \ HTTPStatus.NOT_FOUND.value else: logger.error( 'Subscription is not deleted due to associated MGs were UNLOCKED ' '(or) under update process to LOCKED') return {'error': 'Subscription is not deleted due to the following MGs were UNLOCKED ' '(or) under update process to LOCKED', 'measurementGroupNames': [{'measurementGroupName': mg.measurement_group_name}for mg in unlocked_locking_mgs]}, \ HTTPStatus.CONFLICT.value except Exception as exception: logger.error(f'Try again, subscription with name {subscription_name}' f'is not deleted due to following exception: {exception}') return {'error': f'Try again, subscription with name {subscription_name}' f'is not deleted due to following exception: {exception}'}, \ HTTPStatus.INTERNAL_SERVER_ERROR.value
def update_admin_state(subscription_name, measurement_group_name, body): """ Performs administrative state update for the respective subscription and measurement group name Args: subscription_name (String): Name of the subscription. measurement_group_name (String): Name of the measurement group body (dict): Request body with admin state to update. Returns: string, HTTPStatus: Successfully updated admin state, 200 string, HTTPStatus: Invalid request details, 400 string, HTTPStatus: Cannot update as Locked request is in progress, 409 string, HTTPStatus: Exception details of server failure, 500 """ logger.info( 'Performing administration status update for measurement group ' f'with sub name: {subscription_name} and measurement ' f'group name: {measurement_group_name} to {body["administrativeState"]} status' ) response = 'Successfully updated admin state', HTTPStatus.OK.value try: meas_group = measurement_group_service.query_meas_group_by_name( subscription_name, measurement_group_name) measurement_group_service.update_admin_status( meas_group, body["administrativeState"]) except InvalidDataException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.BAD_REQUEST.value except DataConflictException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.CONFLICT.value except Exception as exception: logger.error( 'Update admin status request was not processed for sub name: ' f'{subscription_name} and meas group name: ' f'{measurement_group_name} due to Exception : {exception}') response = 'Update admin status request was not processed for sub name: '\ f'{subscription_name} and meas group name: {measurement_group_name}'\ f' due to Exception : {exception}', HTTPStatus.INTERNAL_SERVER_ERROR return response