group-based-policy/gbpservice/nfp/orchestrator/modules/service_orchestrator.py

2952 lines
135 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron.common import rpc as n_rpc
from neutron import context as n_context
from neutron.db import api as db_api
from oslo_log import helpers as log_helpers
import oslo_messaging
from gbpservice._i18n import _
from gbpservice.nfp.common import constants as nfp_constants
from gbpservice.nfp.common import exceptions as nfp_exc
from gbpservice.nfp.common import topics as nfp_rpc_topics
from gbpservice.nfp.core import context as module_context
from gbpservice.nfp.core.event import Event
from gbpservice.nfp.core import module as nfp_api
from gbpservice.nfp.core import path as nfp_path
from gbpservice.nfp.core.rpc import RpcAgent
from gbpservice.nfp.lib import nfp_context_manager as nfp_ctx_mgr
from gbpservice.nfp.lib import transport
from gbpservice.nfp.orchestrator.config_drivers import heat_driver
from gbpservice.nfp.orchestrator.db import nfp_db as nfp_db
from gbpservice.nfp.orchestrator.openstack import openstack_driver
import sys
import traceback
from gbpservice.nfp.core import log as nfp_logging
LOG = nfp_logging.getLogger(__name__)
STOP_POLLING = {'poll': False}
CONTINUE_POLLING = {'poll': True}
GATEWAY_SERVICES = [nfp_constants.FIREWALL, nfp_constants.VPN]
def rpc_init(controller, config):
rpcmgr = RpcHandler(config, controller)
agent = RpcAgent(controller,
host=config.host,
topic=nfp_rpc_topics.NFP_NSO_TOPIC,
manager=rpcmgr)
configurator_rpcmgr = RpcHandlerConfigurator(config, controller)
configurator_agent = RpcAgent(
controller,
host=config.host,
topic=nfp_rpc_topics.NFP_NSO_CONFIGURATOR_TOPIC,
manager=configurator_rpcmgr)
controller.register_rpc_agents([agent, configurator_agent])
def events_init(controller, config, service_orchestrator):
events = ['DELETE_NETWORK_FUNCTION',
'CREATE_NETWORK_FUNCTION_INSTANCE',
'DELETE_NETWORK_FUNCTION_INSTANCE',
'DEVICE_CREATED',
'DEVICE_ACTIVE', 'DEVICE_DELETED',
'DEVICE_CREATE_FAILED', 'SEND_USER_CONFIG',
'CHECK_HEAT_CONFIG_RESULT', 'APPLY_USER_CONFIG',
'APPLY_USER_CONFIG_BASEMODE',
'DELETE_USER_CONFIG', 'UPDATE_USER_CONFIG',
'POLICY_TARGET_ADD', 'POLICY_TARGET_REMOVE',
'CONSUMER_ADD', 'CONSUMER_REMOVE',
'APPLY_USER_CONFIG_IN_PROGRESS',
'INITIATE_USER_CONFIG',
'UPDATE_NETWORK_FUNCTION_DESCRIPTION',
'UPDATE_USER_CONFIG_PREPARING_TO_START',
'UPDATE_USER_CONFIG_IN_PROGRESS',
'UPDATE_USER_CONFIG_STILL_IN_PROGRESS',
'DELETE_USER_CONFIG_IN_PROGRESS',
'CONFIG_APPLIED', 'USER_CONFIG_APPLIED', 'USER_CONFIG_DELETED',
'USER_CONFIG_DELETE_FAILED', 'USER_CONFIG_UPDATE_FAILED',
'USER_CONFIG_FAILED', 'CHECK_USER_CONFIG_COMPLETE',
'SERVICE_CONFIGURED', 'CREATE_NETWORK_FUNCTION_INSTANCE_DB',
'DELETE_NETWORK_FUNCTION_DB']
events_to_register = []
for event in events:
events_to_register.append(
Event(id=event, handler=service_orchestrator))
controller.register_events(events_to_register)
def nfp_module_init(controller, config):
events_init(controller, config, ServiceOrchestrator(controller, config))
rpc_init(controller, config)
class RpcHandler(object):
"""RPC Handler for Node Driver to NFP.
Network Function methods are invoked in an RPC Call by the
node driver and data has to be returned by the orchestrator.
"""
RPC_API_VERSION = '1.0'
target = oslo_messaging.Target(version=RPC_API_VERSION)
def __init__(self, conf, controller):
super(RpcHandler, self).__init__()
self.conf = conf
self._controller = controller
# REVISIT (mak): Can a ServiceOrchestrator object be
# initialized here and used for each rpc ?
@log_helpers.log_method_call
def create_network_function(self, context, network_function):
'''Create Network Function.
Invoked in an RPC Call. Return the Network function DB object
created. Results in an Event for async processing of Network
Function Instance
'''
module_context.init(network_function)
LOG.info("Received RPC call for CREATE NETWORK FUNCTION for "
"tenant:%(tenant_id)s",
{'tenant_id': network_function[
'resource_owner_context']['tenant_id']})
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
return service_orchestrator.create_network_function(
context, network_function)
@log_helpers.log_method_call
def get_network_function(self, context, network_function_id):
'''Invoked in an RPC Call. Return the Network function DB object'''
module_context.init()
LOG.debug("Received RPC call for GET NETWORK FUNCTION for NFI %s",
network_function_id)
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
return service_orchestrator.get_network_function(
context, network_function_id)
@log_helpers.log_method_call
def get_network_functions(self, context, filters=None):
'''Invoked in an RPC Call.
Returns the Network functions from DB
'''
module_context.init()
LOG.info("Received RPC call for GET NETWORK FUNCTIONS ")
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
return service_orchestrator.get_network_functions(
context, filters)
@log_helpers.log_method_call
def update_network_function(self, context, network_function_id,
config):
'''Update Network Function Configuration.
Invoked in an RPC call. Return the updated Network function DB object.
Results in an Event for async processing of Network Function Instance.
'''
module_context.init()
LOG.info("Received RPC call for UPDATE NETWORK FUNCTION for NF:"
"%(network_function_id)s",
{'network_function_id': network_function_id})
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
service_orchestrator.update_network_function(
context, network_function_id, config)
@log_helpers.log_method_call
def delete_network_function(self, context, network_function_id,
network_function_data):
'''Delete the network Function.
Invoked in an RPC call. Return the updated Network function DB object.
Results in an Event for async processing of Network Function Instance.
'''
module_context.init()
LOG.info("Received RPC call for DELETE NETWORK FUNCTION for NF:"
"%(network_function_id)s",
{'network_function_id': network_function_id})
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
service_orchestrator.delete_network_function(
context, network_function_id, network_function_data)
@log_helpers.log_method_call
def policy_target_added_notification(self, context, network_function_id,
policy_target):
'''Update Configuration to react to member addition.
Invoked in an RPC call. Return the updated Network function DB object.
Results in an Event for async processing of Network Function Instance.
'''
module_context.init()
LOG.info("Received RPC call for POLICY TARGET ADDED NOTIFICATION "
"for NF:"
" %(network_function_id)s",
{'network_function_id': network_function_id})
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
service_orchestrator.handle_policy_target_added(
context, network_function_id, policy_target)
@log_helpers.log_method_call
def policy_target_removed_notification(self, context, network_function_id,
policy_target):
'''Update Configuration to react to member deletion.
Invoked in an RPC call. Return the updated Network function DB object.
Results in an Event for async processing of Network Function Instance.
'''
module_context.init()
LOG.info("Received RPC call for POLICY TARGET REMOVED "
"NOTIFICATION for NF:%(network_function_id)s",
{'network_function_id': network_function_id})
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
service_orchestrator.handle_policy_target_removed(
context, network_function_id, policy_target)
@log_helpers.log_method_call
def consumer_ptg_added_notification(self, context, network_function_id,
policy_target_group):
'''Update Configuration to react to consumer PTG creation.
Invoked in an RPC call. Return the updated Network function DB object.
Results in an Event for async processing of Network Function Instance.
'''
module_context.init()
LOG.info("Received RPC call CONSUMER PTG ADDED NOTIFICATION "
"for NF:%(network_function_id)s",
{'network_function_id': network_function_id})
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
service_orchestrator.handle_consumer_ptg_added(
context, network_function_id, policy_target_group)
@log_helpers.log_method_call
def consumer_ptg_removed_notification(self, context, network_function_id,
policy_target_group):
'''Update Configuration to react to consumer PTG deletion.
Invoked in an RPC call. Return the updated Network function DB object.
Results in an Event for async processing of Network Function Instance.
'''
module_context.init()
LOG.info("Received RPC call for CONSUMER PTG REMOVED NOTIFICATION "
"for NF:%(network_function_id)s",
{'network_function_id': network_function_id})
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
service_orchestrator.handle_consumer_ptg_removed(
context, network_function_id, policy_target_group)
@log_helpers.log_method_call
def get_network_function_details(self, context, network_function_id):
'''Invoked in an RPC Call.
Return the Network function Details object
'''
module_context.init()
LOG.debug("Received RPC call for GET NETWORK FUNCTION DETAILS in "
"for NF:%s",
network_function_id)
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
return service_orchestrator.get_network_function_details(
network_function_id)
@log_helpers.log_method_call
def get_port_info(self, context, port_id):
'''Invoked in an RPC Call. Return the Port Info Details object'''
module_context.init()
LOG.debug("Received RPC call for GET PORT INFO in "
"for PORT ID:%s",
port_id)
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
return service_orchestrator.get_port_info(port_id)
@log_helpers.log_method_call
def get_network_function_context(self, context, network_function_id):
'''Invoked in an RPC Call.
Return the Network function context
'''
module_context.init()
LOG.debug("Received RPC call for GET NETWORK FUNCTION CONTEXT in "
"for NF:%s",
network_function_id)
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
return service_orchestrator.get_network_function_context(
network_function_id)
@log_helpers.log_method_call
def get_plumbing_info(self, context, request_info):
module_context.init()
LOG.debug("Received RPC call for GET PLUMBING INFO "
"for request info:%s",
request_info)
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
return service_orchestrator.get_pt_info_for_plumbing(request_info)
class RpcHandlerConfigurator(object):
"""RPC Handler for notificationrpcs from
Configurator to orchestrator.
"""
RPC_API_VERSION = '1.0'
target = oslo_messaging.Target(version=RPC_API_VERSION)
def __init__(self, conf, controller):
super(RpcHandlerConfigurator, self).__init__()
self.conf = conf
self._controller = controller
self.rpc_event_mapping = {
'heat': ['CHECK_HEAT_CONFIG_RESULT',
'DELETE_USER_CONFIG',
'UPDATE_USER_CONFIG',
'POLICY_TARGET_ADD',
'POLICY_TARGET_REMOVE',
'CONSUMER_ADD',
'CONSUMER_REMOVE']
}
def _log_event_created(self, event_id, event_data):
network_function_instance = event_data.get('network_function_instance')
if network_function_instance:
NF = network_function_instance.get('network_function_id')
NFI = network_function_instance.get('id')
else:
NF = None
NFI = None
if NF and NFI:
LOG.info("Created event %(event_name)s with NF:%(nf)s "
"and NFI:%(nfi)s ",
{'event_name': event_id,
'nf': NF,
'nfi': NFI})
else:
LOG.info("Created event %(event_name)s ",
{'event_name': event_id})
def _create_event(self, event_id, event_data=None,
is_poll_event=False, original_event=None,
serialize=False, max_times=10):
if is_poll_event:
ev = self._controller.new_event(
id=event_id, data=event_data,
serialize=original_event.sequence,
binding_key=original_event.binding_key,
key=original_event.key)
LOG.debug("poll event started for %s", (ev.id))
self._controller.poll_event(ev, max_times=10)
else:
if serialize:
network_function_id = event_data['network_function_id']
ev = self._controller.new_event(
id=event_id, data=event_data,
binding_key=network_function_id,
key=network_function_id,
serialize=True)
else:
ev = self._controller.new_event(
id=event_id,
data=event_data)
self._controller.post_event(ev)
self._log_event_created(event_id, event_data)
@log_helpers.log_method_call
def network_function_notification(self, context, notification_data):
nfp_context = module_context.init()
info = notification_data.get('info')
responses = notification_data.get('notification')
request_info = info.get('context')
operation = request_info.get('operation')
logging_context = request_info.get('logging_context', {})
nfp_context['log_context'] = logging_context
if 'nfp_context' in request_info:
nfp_context.update(request_info['nfp_context'])
serialize = False
for response in responses:
resource = response.get('resource')
data = response.get('data')
result = data.get('status_code')
if result.lower() != 'success':
if operation == 'create':
event_id = self.rpc_event_mapping[resource][0]
elif operation == 'delete':
# No need to handle this
# event_id = self.rpc_event_mapping[resource][1]
return
elif operation == 'update':
serialize = True
event_id = self.rpc_event_mapping[resource][2]
elif operation == 'pt_add':
serialize = True
event_id = self.rpc_event_mapping[resource][3]
elif operation == 'pt_remove':
serialize = True
event_id = self.rpc_event_mapping[resource][4]
elif operation == 'consumer_add':
serialize = True
event_id = self.rpc_event_mapping[resource][5]
else:
serialize = True
event_id = self.rpc_event_mapping[resource][6]
break
else:
if operation == 'delete':
event_id = 'USER_CONFIG_DELETED'
else:
event_id = 'CONFIG_APPLIED'
nf_id = request_info.pop('nf_id')
nfi_id = request_info.pop('nfi_id')
nfd_id = request_info.pop('nfd_id')
request_info['network_function_id'] = nf_id
request_info['network_function_instance_id'] = nfi_id
request_info['network_function_device_id'] = nfd_id
event_data = request_info
self._create_event(event_id=event_id,
event_data=event_data, serialize=serialize)
class NFPDbPatch(nfp_db.NFPDbBase):
"""Patch for Db class.
This class is used by service orchestrator to complete the path.
In the CREATE/UPDATE operations, at last service orchestrator
invokes update_network_function to update status to be ACTIVE/ERROR,
and there are many error paths. Instead of doing 'path_complete'
at multiple places, patched the Db class to override update &
delete network_function methods. Here, the path is completed and
then the base class methods are invoked to do the actual db operation.
"""
def __init__(self, controller):
self._controller = controller
super(NFPDbPatch, self).__init__()
def update_network_function(self, session, network_function_id,
updated_network_function):
status = updated_network_function.get('status')
if status == 'ACTIVE' or status == 'ERROR':
self._controller.path_complete_event()
return super(NFPDbPatch, self).update_network_function(
session, network_function_id, updated_network_function)
def delete_network_function(self, session, network_function_id):
self._controller.path_complete_event()
return super(NFPDbPatch, self).delete_network_function(
session, network_function_id)
class ServiceOrchestrator(nfp_api.NfpEventHandler):
"""Orchestrator For Network Services
This class handles the orchestration of Network Function lifecycle.
It deals with logical service resources - Network Functions and Network
Function Instances. There is a one-to-many mapping between Network
Functions and Network Function instances. For eg. a Network Function in
HA mode might have two Network Function Instances - Active, Standby
whereas a Network Function in Cluster mode might have more than 2 Network
Function Instances. This module interacts with Device Orchestrator and
Config driver.
Workflow for create:
1) create_network_function is called in the context of an RPC call. This
method generates an event CREATE_NETWORK_FUNCTION_INSTANCE
2) Event handler for CREATE_NETWORK_FUNCTION_INSTANCE. Here a DB entry is
created and generates an event CREATE_NETWORK_FUNCTION_DEVICE.
3) The Device Orchestrator module handles this event and generates an event
DEVICE_CREATED or DEVICE_CREATE_FAILED
4) Event handler for DEVICE_CREATED event updates the Network Function
Instance DB object with the created Network Function Device ID
5) Event handler for DEVICE_CREATE_FAILED event updates the Network
Function Instance and Network Function DB with status ERROR
6) Device orchestrator could then generate DEVICE_ACTIVE or
DEVICE_CREATE_FAILED based on the device being healthy or it being not
reachable
7) Event handler for DEVICE_ACTIVE updates Network Function Instance to
Active, invokes config driver (heat) to apply user provided service config.
A poll event APPLY_USER_CONFIG_IN_PROGRESS is then created.
8) Event handler for poll event APPLY_USER_CONFIG_IN_PROGRESS checks
whether the configuration is applied successfully
9) If the config driver returns COMPLETED or ERROR, the poll event is
stopped and the Network Function is updated to Active or Error. If it
returns IN_PROGRESS, the poll event is continued.
"""
# REVISIT(ashu): Split this into multiple manageable classes
def __init__(self, controller, config):
self._controller = controller
self.conf = config
self.db_handler = NFPDbPatch(controller)
self.gbpclient = openstack_driver.GBPClient(config)
self.keystoneclient = openstack_driver.KeystoneClient(config)
self.config_driver = heat_driver.HeatDriver(config)
neutron_context = n_context.get_admin_context()
self.configurator_rpc = NSOConfiguratorRpcApi(neutron_context, config)
self.UPDATE_USER_CONFIG_MAXRETRY = (
nfp_constants.UPDATE_USER_CONFIG_PREPARING_TO_START_MAXRETRY)
self.UPDATE_USER_CONFIG_STILL_IN_PROGRESS_MAXRETRY = (
nfp_constants.UPDATE_USER_CONFIG_STILL_IN_PROGRESS_MAXRETRY)
self.status_map = {
'pt_add': {'status': 'PT_ADD_IN_PROGRESS',
'status_description': 'pt addition is in progress'},
'pt_remove': {'status': 'PT_REMOVE_IN_PROGRESS',
'status_description': 'pt deletion is in progress'},
'ptg_add': {'status': 'PTG_ADD_IN_PROGRESS',
'status_description': 'ptg addition is in progress'},
'ptg_remove': {'status': 'PTG_REMOVE_IN_PROGRESS',
'status_description': (
'ptg deletion is in progress')},
}
@property
def db_session(self):
return db_api.get_session()
def event_method_mapping(self, event_id):
event_handler_mapping = {
"DELETE_NETWORK_FUNCTION": self.delete_network_function,
"CREATE_NETWORK_FUNCTION_INSTANCE": (
self.create_network_function_instance),
"DELETE_NETWORK_FUNCTION_INSTANCE": (
self.delete_network_function_instance),
"DEVICE_CREATED": self.handle_device_created,
"DEVICE_ACTIVE": self.handle_device_active,
"SEND_USER_CONFIG": self.send_user_config,
"DEVICE_DELETED": self.handle_device_deleted,
"DEVICE_CREATE_FAILED": self.handle_device_create_failed,
"APPLY_USER_CONFIG": self.apply_user_config,
"APPLY_USER_CONFIG_BASEMODE": self.apply_user_config_basemode,
"CHECK_HEAT_CONFIG_RESULT": self.check_heat_config_result,
"DELETE_USER_CONFIG": self.delete_user_config,
"UPDATE_USER_CONFIG": self.handle_update_user_config,
"POLICY_TARGET_ADD": self.policy_target_add_user_config,
"POLICY_TARGET_REMOVE": self.policy_target_remove_user_config,
"CONSUMER_ADD": self.consumer_ptg_add_user_config,
"CONSUMER_REMOVE": self.consumer_ptg_remove_user_config,
"INITIATE_USER_CONFIG": self.initiate_user_config,
"UPDATE_NETWORK_FUNCTION_DESCRIPTION": (
self.update_network_function_description),
"APPLY_USER_CONFIG_IN_PROGRESS": (
self.apply_user_config_in_progress),
"CHECK_USER_CONFIG_COMPLETE": (
self.check_for_user_config_complete),
"UPDATE_USER_CONFIG_PREPARING_TO_START": (
self.check_for_user_config_deleted),
"UPDATE_USER_CONFIG_IN_PROGRESS": (
self.handle_continue_update_user_config),
"UPDATE_USER_CONFIG_STILL_IN_PROGRESS": (
self.apply_user_config_in_progress),
"DELETE_USER_CONFIG_IN_PROGRESS": (
self.check_for_user_config_deleted_fast),
"CONFIG_APPLIED": self.handle_config_applied,
"USER_CONFIG_APPLIED": self.handle_user_config_applied,
"USER_CONFIG_DELETED": self.handle_user_config_deleted,
"USER_CONFIG_DELETE_FAILED": self.handle_user_config_delete_failed,
"USER_CONFIG_UPDATE_FAILED": self.handle_update_user_config_failed,
"USER_CONFIG_FAILED": self.handle_user_config_failed,
"SERVICE_CONFIGURED": self.handle_service_configured,
"CREATE_NETWORK_FUNCTION_INSTANCE_DB": (
self.create_network_function_instance_db),
"DELETE_NETWORK_FUNCTION_DB": self.delete_network_function_db
}
if event_id not in event_handler_mapping:
raise Exception(_("Invalid Event ID"))
else:
return event_handler_mapping[event_id]
def handle_event(self, event):
event_data = event.context
network_function_instance = event_data.get(
'network_function_instance')
if network_function_instance:
NF = network_function_instance.get('network_function_id')
NFI = network_function_instance.get('id')
else:
NF = None
NFI = None
if NF and NFI:
LOG.info("Received event %(event_name)s with NF:%(nf)s and "
"NFI:%(nfi)s ",
{'event_name': event.id,
'nf': NF,
'nfi': NFI})
else:
LOG.info("Received event %(event_name)s ",
{'event_name': event.id})
try:
event_handler = self.event_method_mapping(event.id)
event_handler(event)
except Exception as e:
LOG.exception("Error in processing event: %(event_id)s for "
"event data %(event_data)s. Error: %(error)s",
{'event_id': event.id, 'event_data': event.data,
'error': e})
_, _, tb = sys.exc_info()
traceback.print_tb(tb)
raise e
def handle_poll_event(self, event):
LOG.info("Received poll event %(id)s",
{'id': event.id})
try:
event_handler = self.event_method_mapping(event.id)
return event_handler(event)
except Exception:
LOG.exception("Error in processing poll event: "
"%(event_id)s", {'event_id': event.id})
def event_cancelled(self, event, reason):
nfp_context = event.context
if event.id == 'CHECK_USER_CONFIG_COMPLETE':
network_function = nfp_context['network_function']
LOG.info("Applying user config failed for "
"NF:%(network_function_id)s "
"with reason %(reason)s"
" ", {'network_function_id': network_function[
'id'], 'reason': str(reason)})
operation = nfp_context['log_context'].get('path')
LOG.error("[Event:Service%(operation)sFailed]",
{'operation': operation.capitalize()})
LOG.event('%s network function failed.' % operation.capitalize(),
stats_type=nfp_constants.error_event)
binding_key = nfp_context['service_details'][
'service_vendor'].lower() + network_function['id']
# Complete the original event INITIATE_USER_CONFIG here
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = self._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
apply_config_event.binding_key = binding_key
self._controller.event_complete(
apply_config_event, result="FAILED")
elif event.id == 'APPLY_USER_CONFIG_IN_PROGRESS' or (
event.id == 'UPDATE_USER_CONFIG_STILL_IN_PROGRESS'):
request_data = event.data
LOG.info("Applying user config failed for "
"NF: %(network_function_id)s data:"
"%(data)s with reason %(reason)s"
"", {'data': request_data,
'network_function_id': request_data[
'network_function_id'],
'reason': str(reason)})
updated_network_function = {'status': nfp_constants.ERROR}
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
request_data['network_function_id'],
updated_network_function)
operation = nfp_context['log_context'].get('path')
LOG.error("[Event:Service%(operation)sFailed]",
{'operation': operation.capitalize()})
LOG.event('%s network function failed.' % operation.capitalize(),
stats_type=nfp_constants.error_event)
elif event.id == 'DELETE_USER_CONFIG_IN_PROGRESS' or (
event.id == 'UPDATE_USER_CONFIG_PREPARING_TO_START'):
request_data = event.data
event_data = {
'network_function_id': request_data['network_function_id']
}
if event.id == 'DELETE_USER_CONFIG_IN_PROGRESS':
ducf_event = self._controller.new_event(
id='DELETE_USER_CONFIG',
key=request_data['network_function_id'],
binding_key=request_data['network_function_id'],
desc_dict=request_data['event_desc'])
self._controller.event_complete(ducf_event, result="FAILED")
self._create_event('USER_CONFIG_DELETE_FAILED',
event_data=event_data, is_internal_event=True)
def handle_exception(self, event, exception):
return ExceptionHandler.handle(self, event, exception)
def _log_event_created(self, event_id, event_data):
network_function_instance = event_data.get(
'network_function_instance')
if network_function_instance:
NF = network_function_instance.get('network_function_id')
NFI = network_function_instance.get('id')
else:
NF = None
NFI = None
if NF and NFI:
LOG.info("Created event %(event_name)s with NF:%(nf)s and "
"NFI:%(nfi)s ",
{'event_name': event_id,
'nf': NF,
'nfi': NFI})
else:
LOG.info("Created event %(event_name)s ",
{'event_name': event_id})
# REVISIT(ashu): Merge this _create_event, and above one to have
# single function.
def _create_event(self, event_id, event_data=None,
key=None, binding_key=None, serialize=False,
is_poll_event=False, original_event=None,
is_internal_event=False, max_times=20):
if not is_internal_event:
if is_poll_event:
ev = self._controller.new_event(
id=event_id, data=event_data,
serialize=original_event.sequence,
binding_key=original_event.binding_key,
key=original_event.desc.uuid)
LOG.debug("poll event started for %s", (ev.id))
self._controller.poll_event(ev, max_times=max_times)
else:
if original_event:
ev = self._controller.new_event(
id=event_id, data=event_data,
serialize=original_event.sequence,
binding_key=original_event.binding_key,
key=original_event.desc.uuid)
else:
ev = self._controller.new_event(
id=event_id,
data=event_data)
self._controller.post_event(ev)
nfp_context = module_context.get()
self._log_event_created(event_id, nfp_context)
else:
nfp_context = module_context.get()
if original_event:
event = self._controller.new_event(
id=event_id, data=event_data,
serialize=original_event.sequence,
binding_key=original_event.binding_key,
key=original_event.desc.uuid,
context=nfp_context)
else:
# Same module API, so calling corresponding function
# directly.
event = self._controller.new_event(
id=event_id,
data=event_data,
context=nfp_context)
self.handle_event(event)
def _get_base_mode_support(self, service_profile_id):
with nfp_ctx_mgr.KeystoneContextManager as kcm:
admin_token = kcm.retry(self.keystoneclient.get_admin_token)
with nfp_ctx_mgr.GBPContextManager as gcm:
service_profile = gcm.retry(self.gbpclient.get_service_profile,
admin_token, service_profile_id)
service_details = transport.parse_service_flavor_string(
service_profile['service_flavor'])
resource_data = {'admin_token': admin_token,
'service_profile': service_profile,
'service_details': service_details}
base_mode_support = (True if service_details['device_type'] == 'None'
else False)
return base_mode_support, resource_data
def _get_service_type(self, service_profile_id):
with nfp_ctx_mgr.KeystoneContextManager as kcm:
admin_token = kcm.retry(self.keystoneclient.get_admin_token)
with nfp_ctx_mgr.GBPContextManager as gcm:
service_profile = gcm.retry(self.gbpclient.get_service_profile,
admin_token, service_profile_id)
service_type = service_profile['service_type']
return service_type
def update_network_function_user_config(self, network_function_id,
service_config_str,
operation):
tag_str, config_str = self.config_driver.parse_template_config_string(
service_config_str)
if not config_str:
LOG.error('Exception while parsing config string, config '
'string: %(config_str)s is improper for '
'network_function id: %(network_function_id)s',
{'config_str': service_config_str,
'network_function_id': network_function_id})
self.handle_driver_error(network_function_id)
return None
if tag_str != nfp_constants.CONFIG_INIT_TAG:
network_function_details = self.get_network_function_details(
network_function_id)
service_type = network_function_details.pop('service_type')
if not service_type:
service_type = self._get_service_type(
network_function_details['network_function'][
'service_profile_id'])
network_function_data = {
'network_function_details': network_function_details,
'service_type': service_type
}
rpc_method = getattr(self.configurator_rpc, operation +
'_network_function_user_config')
rpc_method(network_function_data, service_config_str, tag_str)
else:
# Place holder for calling config_init API
pass
def update_consumer_ptg(self, network_function_data,
service_config_str, operation):
tag_str, config_str = self.config_driver.parse_template_config_string(
service_config_str)
network_function_id = network_function_data[
'network_function_details']['network_function']['id']
if not config_str:
LOG.error('Exception while parsing config string, config '
'string: %(config_str)s is improper for '
'network_function id: %(network_function_id)s',
{'config_str': service_config_str,
'network_function_id': network_function_id})
self.handle_driver_error(network_function_id)
return None
if tag_str != nfp_constants.CONFIG_INIT_TAG:
rpc_method = getattr(self.configurator_rpc, operation +
'_user_config')
rpc_method(network_function_data, service_config_str, tag_str)
else:
# Place holder for calling config_init API
pass
def create_network_function_user_config(self, network_function_id,
service_config_str):
self.update_network_function_user_config(network_function_id,
service_config_str,
operation='create')
def delete_network_function_user_config(self, network_function_id,
service_config_str):
self.update_network_function_user_config(network_function_id,
service_config_str,
operation='delete')
def consumer_add_user_config(self, network_function_data,
service_config_str):
self.update_consumer_ptg(network_function_data,
service_config_str,
operation='consumer_add')
def consumer_remove_user_config(self, network_function_data,
service_config_str):
self.update_consumer_ptg(network_function_data,
service_config_str,
operation='consumer_remove')
def pt_add_user_config(self, network_function_data,
service_config_str):
self.update_consumer_ptg(network_function_data,
service_config_str,
operation='policy_target_add')
def pt_remove_user_config(self, network_function_data,
service_config):
self.update_consumer_ptg(network_function_data,
service_config,
operation='policy_target_remove')
def _report_logging_info(self, nf, nfi, service_type,
service_vendor):
LOG.info("[TenantID:%(tenant_id)s, "
"ServiceChainID:%(service_chain_id)s, "
"ServiceInstanceID:%(service_instance_id)s, "
"ServiceType:%(service_type)s, "
"ServiceProvider:%(service_provider)s]",
{'tenant_id': nf['tenant_id'],
'service_chain_id': nf['service_chain_id'],
'service_instance_id': nfi['id'],
'service_type': service_type,
'service_provider': service_vendor})
def _validate_service_vendor(self, service_vendor):
if (service_vendor not in self.conf.orchestrator.supported_vendors):
raise Exception(
_("The NFP Node driver does not support this service "
"profile with the service vendor %s.") % service_vendor)
def create_network_function(self, context, network_function_info):
self._validate_create_service_input(context, network_function_info)
nfp_context = module_context.get()
service_profile = network_function_info['service_profile']
service_details = transport.parse_service_flavor_string(
service_profile['service_flavor'])
with nfp_ctx_mgr.KeystoneContextManager as kcm:
admin_token = kcm.retry(self.keystoneclient.get_admin_token)
admin_tenant_id = kcm.retry(
self.keystoneclient.get_admin_tenant_id, admin_token)
network_function_info['resource_owner_context'][
'admin_token'] = admin_token
network_function_info['resource_owner_context'][
'admin_tenant_id'] = admin_tenant_id
tenant_id = network_function_info['tenant_id']
# GBP or Neutron
# mode = network_function_info['network_function_mode']
service_profile_id = service_profile['id']
service_id = network_function_info['service_chain_node']['id']
service_chain_id = network_function_info[
'service_chain_instance']['id']
base_mode_support = (True if service_details['device_type'] == 'None'
else False)
# REVISIT(ashu): take the first few characters just like neutron does
# with ovs interfaces inside the name spaces..
name = "%s_%s" % (network_function_info[
'service_chain_node']['name'][:6],
network_function_info[
'service_chain_instance']['name'][:6])
service_config_str = network_function_info.pop('service_config')
network_function = {
'name': name,
'description': '',
'tenant_id': tenant_id,
'service_id': service_id, # GBP Service Node or Neutron Service ID
'service_chain_id': service_chain_id, # GBP SC instance ID
'service_profile_id': service_profile_id,
'service_config': service_config_str,
'status': nfp_constants.PENDING_CREATE
}
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.create_network_function(
self.db_session, network_function)
network_function.pop('service_config')
# Update ncp_node_instance_nf_mapping with nf_id
network_function_map = {
'network_function_id': network_function['id'],
'status': nfp_constants.PENDING_CREATE,
'status_details': 'Processing create in orchestrator'
}
with nfp_ctx_mgr.DbContextManager:
self.db_handler.update_node_instance_network_function_map(
self.db_session, service_id, service_chain_id,
network_function_map)
nfp_path.create_path(network_function['id'])
nfp_context['event_desc']['path_type'] = 'create'
nfp_context['event_desc']['path_key'] = network_function['id']
nfp_context['log_context']['path'] = 'create'
nfp_context['log_context']['meta_id'] = network_function['id']
nfp_context['log_context']['auth_token'] = context.auth_token
LOG.info("[Event:ServiceCreateInitiated]")
LOG.event("Started create network function.",
stats_type=nfp_constants.request_event)
nfp_context.update(network_function_info)
service_details['service_type'] = service_profile['service_type']
service_details['network_mode'] = nfp_context['network_function_mode']
nfp_context['network_function'] = network_function
nfp_context['service_details'] = service_details
nfp_context['share_existing_device'] = False
nfp_context['base_mode'] = base_mode_support
LOG.info("Handling RPC call CREATE NETWORK FUNCTION for "
"%(service_type)s with tenant:%(tenant_id)s",
{'tenant_id': tenant_id,
'service_type': service_profile['service_type']})
if base_mode_support:
# Store the context in current thread
# In base mode support, create user config directly, no need to
# create network function instance, network function device first.
self.create_network_function_user_config(network_function['id'],
service_config_str)
else:
# Create and event to perform Network service instance
ev = self._controller.new_event(
id='CREATE_NETWORK_FUNCTION_INSTANCE_DB',
key=network_function['id'])
self._controller.post_event(ev)
# self.create_network_function_instance_db(nfp_context)
return network_function
def update_network_function(self, context, network_function_id,
user_config):
nfp_context = module_context.get()
nfp_path.update_path(network_function_id)
nfp_context['event_desc']['path_type'] = 'update'
nfp_context['event_desc']['path_key'] = network_function_id
nfp_context['log_context']['path'] = 'update'
nfp_context['log_context']['meta_id'] = network_function_id
nfp_context['log_context']['auth_token'] = context.auth_token
# Handle config update
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function_id,
{'service_config': user_config,
'status': nfp_constants.PENDING_UPDATE})
LOG.info("[Event:ServiceUpdateInitiated]")
LOG.event("Started update network function.",
stats_type=nfp_constants.request_event)
self.update_network_function_user_config(network_function_id,
user_config,
operation='update')
def delete_network_function(self, context, network_function_id,
network_function_data):
nfp_context = module_context.get()
nfp_path.delete_path(network_function_id)
nfp_context['event_desc']['path_type'] = 'delete'
nfp_context['event_desc']['path_key'] = network_function_id
nfp_context['log_context']['path'] = 'delete'
nfp_context['log_context']['meta_id'] = network_function_id
nfp_context['log_context']['auth_token'] = context.auth_token
network_function_details = self.get_network_function_details(
network_function_id)
service_config = (
network_function_details['network_function'].pop(
'service_config'))
service_profile_id = network_function_details[
'network_function']['service_profile_id']
base_mode_support, resource_data = (
self._get_base_mode_support(service_profile_id))
with nfp_ctx_mgr.KeystoneContextManager as kcm:
admin_tenant_id = kcm.retry(
self.keystoneclient.get_admin_tenant_id,
resource_data['admin_token'])
network_function_details['admin_tenant_id'] = admin_tenant_id
nfi = network_function_details.get('network_function_instance', None)
nfd = network_function_details.get('network_function_device', None)
nfi_id = nfi.get('id', '-') if nfi else '-'
nfd_id = nfd.get('id', '-') if nfd else '-'
nfp_context['log_context']['nfi_id'] = nfi_id
nfp_context['log_context']['nfd_id'] = nfd_id
if (not base_mode_support and
not network_function_details[
'network_function']['network_function_instances']):
with nfp_ctx_mgr.DbContextManager:
self.db_handler.delete_network_function(
self.db_session, network_function_id)
LOG.info("[Event:ServiceDeleteCompleted]")
LOG.event("Completed delete network function.",
stats_type=nfp_constants.response_event)
# network_function_details['service_type is None because
# nfp core context is not set
# so getting service_type from resource_data
service_type = resource_data['service_profile']['service_type']
LOG.event("Sending service deleted event to controller.",
type='SERVICE_DELETED',
nf_id=network_function_id,
service_type=service_type)
return
network_function_details.update(resource_data)
network_function_details.update(
{'base_mode_support': base_mode_support})
network_function = {
'status': nfp_constants.PENDING_DELETE
}
service_chain_instance_details = {
'service_chain_instance': network_function_data[
'service_chain_instance'],
'provider': network_function_data['provider'],
'consumer': network_function_data['consumer']
}
network_function_details.update(service_chain_instance_details)
with nfp_ctx_mgr.DbContextManager as dcm:
network_function = dcm.lock(
self.db_session,
self.db_handler.update_network_function,
network_function_id, network_function)
nfp_context.update(network_function_details)
LOG.info("[Event:ServiceDeleteInitiated]")
LOG.event("Started delete network function.",
stats_type=nfp_constants.request_event)
if not base_mode_support:
self._create_event('DELETE_NETWORK_FUNCTION_INSTANCE',
event_data=network_function_details,
is_internal_event=True)
dnf_event = self._controller.new_event(
id='DELETE_NETWORK_FUNCTION_DB',
key=network_function_id)
GRAPH = {dnf_event: []}
if network_function['config_policy_id']:
ducf_event = (
self._controller.new_event(id='DELETE_USER_CONFIG',
key=network_function_id,
serialize=True,
binding_key=network_function_id))
GRAPH[dnf_event].append(ducf_event)
else:
self.delete_network_function_user_config(network_function_id,
service_config)
if not base_mode_support:
dnfd_event = self._controller.new_event(
id='DELETE_NETWORK_FUNCTION_DEVICE',
key=network_function_id,
serialize=True,
binding_key=network_function_id)
GRAPH[dnf_event].append(dnfd_event)
self._controller.post_graph(
GRAPH, dnf_event, graph_str='DELETE_NETWORK_FUNCTION_GRAPH')
def delete_user_config(self, event):
network_function_details = event.context
network_function_info = network_function_details['network_function']
if not network_function_info['config_policy_id']:
self._controller.event_complete(event, result="SUCCESS")
return
config_policy_id = self.config_driver.delete_config(
network_function_info['config_policy_id'],
network_function_info['tenant_id'],
network_function_info)
request_data = {
'config_policy_id': network_function_info['config_policy_id'],
'tenant_id': network_function_info['tenant_id'],
'network_function_id': network_function_info['id'],
'action': 'delete'
}
if not config_policy_id:
# self._create_event('USER_CONFIG_DELETE_FAILED',
# event_data=request_data, is_internal_event=True)
self._controller.event_complete(event, result="FAILED")
return
request_data['event_desc'] = event.desc.to_dict()
self._create_event(
'DELETE_USER_CONFIG_IN_PROGRESS',
event_data=request_data,
is_poll_event=True, original_event=event,
max_times=nfp_constants.DELETE_USER_CONFIG_IN_PROGRESS_MAXRETRY)
def _update_nfp_context(self, nfp_context):
provider = nfp_context['provider']
consumer = nfp_context['consumer']
provider['pt'] = provider['pt'][0]
provider['ptg'] = provider['ptg'][0]
provider['port'] = provider['port'][0]
if consumer['pt']:
consumer['pt'] = consumer['pt'][0]
if consumer['ptg']:
consumer['ptg'] = consumer['ptg'][0]
if consumer['port']:
consumer['port'] = consumer['port'][0]
def create_network_function_instance_db(self, event):
nfp_context = event.context
network_function = nfp_context['network_function']
service_details = nfp_context['service_details']
port_info = []
# REVISIT(ashu): Only pick few chars from id
name = '%s_%s' % (network_function['id'][:3],
network_function['name'])
create_nfi_request = {
'name': name,
'tenant_id': network_function['tenant_id'],
'status': nfp_constants.PENDING_CREATE,
'network_function_id': network_function['id'],
'service_type': service_details['service_type'],
'service_vendor': service_details['service_vendor'],
'share_existing_device': nfp_context['share_existing_device'],
'port_info': port_info,
}
with nfp_ctx_mgr.DbContextManager:
nfi_db = self.db_handler.create_network_function_instance(
self.db_session, create_nfi_request)
# Sending LogMeta Details to visibility
self._report_logging_info(network_function,
nfi_db,
service_details['service_type'],
service_details['service_vendor'])
nfp_context['network_function_instance'] = nfi_db
self._update_nfp_context(nfp_context)
ev = self._controller.new_event(
id='CREATE_NETWORK_FUNCTION_INSTANCE',
key=network_function['id'])
self._controller.post_event(ev)
self._controller.event_complete(event)
def create_network_function_instance(self, event):
nfp_context = event.context
network_function = nfp_context['network_function']
consumer = nfp_context['consumer']
provider = nfp_context['provider']
network_function_instance = nfp_context[
'network_function_instance']
port_info = []
for ele in [consumer, provider]:
if ele['pt']:
# REVISIT(ashu): Only pick few chars from id
port_info.append(
{'id': ele['pt']['id'],
'port_model': ele['port_model'],
'port_classification': ele['port_classification']
})
nfi = {
'port_info': port_info
}
with nfp_ctx_mgr.DbContextManager:
nfi = self.db_handler.update_network_function_instance(
self.db_session, network_function_instance['id'], nfi)
nfp_context['network_function_instance'] = nfi
nfp_context['log_context']['nfi_id'] = nfi['id']
LOG.info("Creating event CREATE NETWORK FUNCTION DEVICE "
"for NF: %(network_function_id)s",
{'network_function_id': network_function['id']})
ev = self._controller.new_event(
id='CREATE_NETWORK_FUNCTION_DEVICE',
key=network_function['id'] + nfi['id'])
if nfp_context.get('binding_key'):
ev.sequence = True
ev.binding_key = nfp_context.get('binding_key')
LOG.debug("Acquiring tenant based lock for "
"CREATE_NETWORK_FUNCTION_DEVICE event with binding "
"key: %s, sequence: %s", (
ev.binding_key, ev.sequence))
self._controller.post_event(ev)
if event.binding_key and not nfp_context.get('is_nfi_in_graph'):
LOG.debug("Releasing lock for CREATE_NETWORK_FUNCTION_INSTANCE"
" event for gateway services sharing with binding key:"
" %s", event.binding_key)
self._controller.event_complete(event)
def handle_device_created(self, event):
# Not needed for NFP
"""
request_data = event.data
nfi = {
'network_function_device_id': request_data[
'network_function_device_id']
}
with nfp_ctx_mgr.DbContextManager:
nfi = self.db_handler.update_network_function_instance(
self.db_session,
request_data['network_function_instance_id'], nfi)
self._controller.event_complete(event)
"""
return
def send_user_config(self, event):
nfp_context = event.context
network_function_instance = nfp_context['network_function_instance']
network_function_device = nfp_context['network_function_device']
network_function = nfp_context['network_function']
network_function_instance['status'] = nfp_constants.ACTIVE
network_function_instance[
'network_function_device_id'] = network_function_device['id']
# get service_config from nf
service_config = nfp_context['service_chain_node'].get('config')
nfp_context['event_desc'] = event.desc.to_dict()
nfp_context['key'] = event.key
nfp_context['id'] = event.id
self.create_network_function_user_config(network_function['id'],
service_config)
def handle_device_active(self, event):
request_data = event.data
nfi = {
'status': nfp_constants.ACTIVE,
'network_function_device_id': request_data[
'network_function_device_id']
}
with nfp_ctx_mgr.DbContextManager:
nfi = self.db_handler.update_network_function_instance(
self.db_session,
request_data['network_function_instance_id'], nfi)
network_function = self.db_handler.get_network_function(
self.db_session, nfi['network_function_id'])
service_config = network_function['service_config']
self.create_network_function_user_config(network_function['id'],
service_config)
def check_heat_config_result(self, event):
nfp_context = event.data['nfp_context']
base_mode = nfp_context['base_mode']
if base_mode:
# Create and event to apply user config
self._create_event('APPLY_USER_CONFIG_BASEMODE',
event_data=event.data,
is_internal_event=True)
else:
event_desc = nfp_context['event_desc']
key = nfp_context['key']
id = nfp_context['id']
# Complete this event first
self._controller.event_complete(event)
# Complete the original event here
event = self._controller.new_event(id=id, key=key,
desc_dict=event_desc)
self._controller.event_complete(event, result='SUCCESS')
def apply_user_config_basemode(self, event):
request_data = event.data
network_function_details = self.get_network_function_details(
request_data['network_function_id'])
request_data['config_policy_id'] = self.config_driver.apply_config(
network_function_details) # Heat driver to launch stack
network_function = network_function_details['network_function']
request_data['network_function_id'] = network_function['id']
if not request_data['config_policy_id']:
self._create_event('USER_CONFIG_FAILED',
event_data=request_data, is_internal_event=True)
return
request_data['tenant_id'] = network_function['tenant_id']
request_data['network_function_details'] = network_function_details
LOG.debug("handle_device_active config_policy_id: %s",
request_data['config_policy_id'])
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function['id'],
{'config_policy_id': request_data['config_policy_id'],
'description': network_function['description']})
self._create_event(
'APPLY_USER_CONFIG_IN_PROGRESS',
event_data=request_data,
is_poll_event=True,
original_event=event,
max_times=nfp_constants.APPLY_USER_CONFIG_IN_PROGRESS_MAXRETRY)
def initiate_user_config(self, event):
# Split the user config creation in 2 steps,
# get, update the description in network function and
# apply user config
event_results = event.result
for c_event in event_results:
if c_event.id == "SEND_USER_CONFIG" and (
c_event.result.upper() == "FAILED"):
self._controller.event_complete(event, result="FAILED")
return
elif c_event.id == "SEND_USER_CONFIG" and (
c_event.result.upper() == "HANDLED"):
self._controller.event_complete(
event, result="SUCCESS")
return
nfp_context = event.context
nfp_context['event_desc'] = event.desc.to_dict()
network_function = nfp_context['network_function']
ev = self._controller.new_event(
id='UPDATE_NETWORK_FUNCTION_DESCRIPTION',
key=network_function['id'])
self._controller.post_event(ev)
def update_network_function_description(self, event):
nfp_context = event.context
network_function = nfp_context['network_function']
network_function['description'] = str(network_function['description'])
neutron_resource_desc = (
self.config_driver.get_neutron_resource_description(nfp_context))
if not neutron_resource_desc:
LOG.error(
"Preparing neutron resource description failed in "
"config driver, marking user config as Failed for "
"network function: %(nf)s", {'nf': network_function})
nfp_context['network_function_id'] = network_function['id']
binding_key = nfp_context['service_details'][
'service_vendor'].lower() + network_function['id']
# Complete the original event INITIATE_USER_CONFIG here
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = self._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
apply_config_event.binding_key = binding_key
self._controller.event_complete(
apply_config_event, result="FAILED")
# self._create_event('USER_CONFIG_FAILED',
# event_data=nfp_context, is_internal_event=True)
return
nf_desc = network_function['description'] + \
'\n' + neutron_resource_desc
nfp_context['network_function'].update({'description': nf_desc})
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function['id'],
{'description': nf_desc})
ev = self._controller.new_event(
id='APPLY_USER_CONFIG',
key=network_function['id'])
self._controller.post_event(ev)
self._controller.event_complete(event)
def apply_user_config(self, event):
nfp_context = event.context
network_function = nfp_context['network_function']
nfp_context['config_policy_id'] = self.config_driver.apply_heat_config(
nfp_context) # Heat driver to launch stack
nfp_context['network_function_id'] = network_function['id']
if not nfp_context['config_policy_id']:
# self._create_event('USER_CONFIG_FAILED',
# event_data=nfp_context, is_internal_event=True)
binding_key = nfp_context['service_details'][
'service_vendor'].lower() + network_function['id']
# Complete the original event INITIATE_USER_CONFIG here
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = self._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
apply_config_event.binding_key = binding_key
self._controller.event_complete(
apply_config_event, result="FAILED")
self._controller.event_complete(event, result='FAILED')
return
LOG.debug("handle_device_active config_policy_id: %s",
nfp_context['config_policy_id'])
nfp_context['network_function'].update(
{'config_policy_id': nfp_context['config_policy_id']})
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function['id'],
{'config_policy_id': nfp_context['config_policy_id']})
nfp_context['event_desc'] = event.desc.to_dict()
self._create_event(
'CHECK_USER_CONFIG_COMPLETE',
is_poll_event=True,
original_event=event,
max_times=nfp_constants.CHECK_USER_CONFIG_COMPLETE_MAXRETRY)
self._controller.event_complete(event)
def handle_update_user_config(self, event):
'''
Handler to apply any updates in user config.
Initially checks with config driver whether upadte supported for
service type or not. If not supported first deletes the config(checks
for user config deletion via UPDATE_USER_CONFIG_PREPARING_TO_START
event) and then recreates the config with new changes via
UPDATE_USER_CONFIG_STILL_IN_PROGRESS event.
If update supported, update/create corresponding user config in
UPDATE_USER_CONFIG_IN_PROGRESS event.
'''
request_data = event.data
network_function_details = self.get_network_function_details(
request_data['network_function_id'])
network_function = network_function_details['network_function']
service_profile_id = network_function['service_profile_id']
service_type = self._get_service_type(service_profile_id)
request_data.update({'service_type': service_type})
self._controller.event_complete(event)
self._create_event('UPDATE_USER_CONFIG_IN_PROGRESS',
event_data=request_data,
is_internal_event=True,
original_event=event)
def handle_continue_update_user_config(self, event):
request_data = event.data
network_function_details = self.get_network_function_details(
request_data['network_function_id'])
network_function = network_function_details['network_function']
LOG.info("[Event:ServiceUpdateInitiated]")
LOG.event("Started update network function.",
stats_type=nfp_constants.request_event)
nfi = network_function_details.get('network_function_instance', None)
nfd = network_function_details.get('network_function_device', None)
nfi_id = nfi.get('id', '-') if nfi else '-'
nfd_id = nfd.get('id', '-') if nfd else '-'
nfp_context = event.context
nfp_context['log_context']['nfi_id'] = nfi_id
nfp_context['log_context']['nfd_id'] = nfd_id
original_stack_id = network_function_details[
'network_function']['config_policy_id']
service_type = request_data['service_type']
if not self.config_driver.is_update_config_supported(service_type):
network_function_details['network_function'][
'config_policy_id'] = None
if request_data['operation'] == 'update':
config_id = self.config_driver.update_config(
network_function_details,
network_function_details[
'network_function']['config_policy_id'])
elif request_data['operation'] == 'consumer_add':
config_id = self.config_driver.handle_consumer_ptg_operations(
network_function_details, request_data['consumer_ptg'],
"add")
elif request_data['operation'] == 'consumer_remove':
config_id = self.config_driver.handle_consumer_ptg_operations(
network_function_details, request_data['consumer_ptg'],
"remove")
else:
return
if config_id:
request_data = {
'config_policy_id': config_id,
'tenant_id': network_function['tenant_id'],
'network_function_id': network_function['id'],
'network_function_details': network_function_details,
'operation': request_data['operation'],
'stack_id_to_delete': original_stack_id,
'service_type': service_type
}
else:
event_id = ('USER_CONFIG_UPDATE_FAILED'
if request_data['operation'] == 'update'
else 'USER_CONFIG_FAILED')
self._create_event(event_id,
event_data=request_data,
is_internal_event=True)
if event.binding_key:
self._controller.event_complete(event)
return
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function['id'],
{'config_policy_id': config_id})
self._create_event(
'UPDATE_USER_CONFIG_STILL_IN_PROGRESS',
event_data=request_data,
is_poll_event=True, original_event=event,
max_times=self.UPDATE_USER_CONFIG_STILL_IN_PROGRESS_MAXRETRY)
def handle_device_create_failed(self, event):
request_data = event.data
nfi = {
'status': nfp_constants.ERROR,
}
with nfp_ctx_mgr.DbContextManager:
nfi = self.db_handler.update_network_function_instance(
self.db_session,
request_data['network_function_instance_id'], nfi)
network_function = {'status': nfp_constants.ERROR}
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
nfi['network_function_id'],
network_function)
nfp_context = event.context
operation = nfp_context['log_context'].get('path')
LOG.error("[Event:Service%(operation)sFailed]",
{'operation': operation.capitalize()})
LOG.event('%s network function failed.' % operation.capitalize(),
stats_type=nfp_constants.error_event)
# Trigger RPC to notify the Create_Service caller with status
def handle_driver_error(self, network_function_id):
LOG.error("Error occurred while processing network function "
"CRUD operations, marking network function: %(nf_id)s "
"as ERROR to initiate cleanup.",
{'nf_id': network_function_id})
network_function_details = self.get_network_function_details(
network_function_id)
network_function_id = network_function_details.get(
'network_function')['id']
network_function = {'status': nfp_constants.ERROR}
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function_id, network_function)
nfp_context = module_context.get()
operation = nfp_context['log_context'].get('path')
LOG.error("[Event:Service%(operation)sFailed]",
{'operation': operation.capitalize()})
LOG.event('%s network function failed.' % operation.capitalize(),
stats_type=nfp_constants.error_event)
if network_function_details.get('network_function_instance'):
network_function_instance_id = network_function_details[
'network_function_instance']['id']
nfi = {
'status': nfp_constants.ERROR,
}
with nfp_ctx_mgr.DbContextManager:
nfi = self.db_handler.update_network_function_instance(
self.db_session, network_function_instance_id, nfi)
def _update_network_function_instance(self):
pass
def delete_network_function_instance(self, event):
network_function_details = event.context
nfi_id = network_function_details['network_function_instance']['id']
nfi = {'status': nfp_constants.PENDING_DELETE}
with nfp_ctx_mgr.DbContextManager:
nfi = self.db_handler.update_network_function_instance(
self.db_session, nfi_id, nfi)
network_function_details['network_function_instance'] = nfi
# FIXME: Add all possible validations here
def _validate_create_service_input(self, context, create_service_request):
required_attributes = ["resource_owner_context",
"service_chain_instance",
"service_chain_node", "service_profile",
"service_config", "provider", "consumer",
"network_function_mode"]
if (set(required_attributes) & set(create_service_request.keys()) !=
set(required_attributes)):
missing_keys = (set(required_attributes) -
set(create_service_request.keys()))
raise nfp_exc.RequiredDataNotProvided(
required_data=", ".join(missing_keys),
request="Create Network Function")
if create_service_request['network_function_mode'].lower() == "gbp":
gbp_required_attributes = ["management_ptg_id"]
if (set(gbp_required_attributes) &
set(create_service_request.keys()) !=
set(gbp_required_attributes)):
missing_keys = (set(gbp_required_attributes) -
set(create_service_request.keys()))
raise nfp_exc.RequiredDataNotProvided(
required_data=", ".join(missing_keys),
request="Create Network Function")
service_profile = create_service_request['service_profile']
service_details = transport.parse_service_flavor_string(
service_profile['service_flavor'])
service_vendor = service_details.get('service_vendor')
if (not service_vendor or
not service_details.get('device_type')):
raise Exception(_("service_vendor or device_type not provided in "
"service profile's service flavor field."
"Provided service profile: %s") % service_profile)
self._validate_service_vendor(service_vendor.lower())
@nfp_api.poll_event_desc(
event='APPLY_USER_CONFIG_IN_PROGRESS',
spacing=nfp_constants.APPLY_USER_CONFIG_IN_PROGRESS_SPACING)
def apply_user_config_in_progress(self, event):
request_data = event.data
config_status = self.config_driver.is_config_complete(
request_data['config_policy_id'], request_data['tenant_id'],
request_data['network_function_details'])
if config_status == nfp_constants.ERROR:
LOG.info("Applying user config failed for "
"NF:%(network_function_id)s ", {
'network_function_id':
request_data['network_function_id']})
updated_network_function = {'status': nfp_constants.ERROR}
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
request_data['network_function_id'],
updated_network_function)
operation = event.context['log_context'].get('path')
LOG.error("[Event:Service%(operation)sFailed]",
{'operation': operation.capitalize()})
LOG.event('%s network function failed.' % operation.capitalize(),
stats_type=nfp_constants.error_event)
self._controller.event_complete(event)
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.COMPLETED:
if (request_data.get('operation') in [
'consumer_add',
'consumer_remove', 'update'] and not
self.config_driver.is_update_config_supported(
request_data['service_type'])):
self.config_driver.delete_config(
request_data['stack_id_to_delete'],
request_data['tenant_id'])
request_data = {
'config_policy_id': request_data['stack_id_to_delete'],
'network_function_id': request_data['network_function_id'],
'tenant_id': request_data['tenant_id'],
'action': 'update',
'operation': request_data['operation'],
'service_type': request_data['service_type']
}
self._controller.event_complete(event)
self._create_event(
'UPDATE_USER_CONFIG_PREPARING_TO_START',
event_data=request_data,
is_poll_event=True, original_event=event,
max_times=self.UPDATE_USER_CONFIG_MAXRETRY)
return STOP_POLLING
updated_network_function = {'status': nfp_constants.ACTIVE}
LOG.info("Applying user config is successfull moving "
"NF:%(network_function_id)s to ACTIVE",
{'network_function_id':
request_data['network_function_id']})
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
request_data['network_function_id'],
updated_network_function)
operation = event.context['log_context'].get('path')
LOG.info("[Event:Service%(operation)sCompleted]",
{'operation': operation.capitalize()})
LOG.event('Completed %s network function.' % operation,
stats_type=nfp_constants.response_event)
nf_id = request_data['network_function_id']
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session, nf_id)
service_profile_id = network_function['service_profile_id']
# Revisit(shabbir): service_type should be passed from previous
# event
service_type = self._get_service_type(service_profile_id)
LOG.event('Completed %s network function.' % operation,
type='SERVICE_UPDATED',
nf_id=nf_id,
service_type=service_type)
self._controller.event_complete(event)
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.IN_PROGRESS:
return CONTINUE_POLLING
def handle_service_configured(self, event):
nfp_context = event.context
network_function = nfp_context['network_function']
updated_network_function = {'status': nfp_constants.ACTIVE}
LOG.info("Applying user config is successfull moving "
"NF: %(network_function_id)s to ACTIVE",
{'network_function_id': network_function['id']})
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function['id'],
updated_network_function)
operation = nfp_context['log_context'].get('path')
LOG.info("[Event:Service%(operation)sCompleted]",
{'operation': operation.capitalize()})
LOG.event('Completed %s network function.' % operation,
stats_type=nfp_constants.response_event)
service_type = nfp_context['service_details']['service_type']
nf_id = network_function['id']
LOG.event("Sending service created event to controller.",
type='SERVICE_CREATED',
nf_id=nf_id,
service_type=service_type)
self._controller.event_complete(event)
@nfp_api.poll_event_desc(
event='CHECK_USER_CONFIG_COMPLETE',
spacing=nfp_constants.CHECK_USER_CONFIG_COMPLETE_SPACING)
def check_for_user_config_complete(self, event):
nfp_context = event.context
network_function = nfp_context['network_function']
binding_key = nfp_context[
'service_details'][
'service_vendor'].lower() + network_function['id']
config_status = self.config_driver.check_config_complete(nfp_context)
if config_status == nfp_constants.ERROR:
LOG.info("Applying user config failed for "
"NF: %(network_function_id)s", {
'network_function_id':
network_function['id']})
# Complete the original event APPLY_USER_CONFIG here
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = self._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
apply_config_event.binding_key = binding_key
self._controller.event_complete(
apply_config_event, result="FAILED")
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.COMPLETED:
# Complete the original event DEVICE_ACTIVE here
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = self._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
apply_config_event.binding_key = binding_key
self._controller.event_complete(
apply_config_event, result="SUCCESS")
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.IN_PROGRESS:
return CONTINUE_POLLING
@nfp_api.poll_event_desc(
event='UPDATE_USER_CONFIG_PREPARING_TO_START',
spacing=nfp_constants.UPDATE_USER_CONFIG_PREPARING_TO_START_SPACING)
def check_for_user_config_deleted(self, event):
request_data = event.data
try:
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session,
request_data['network_function_id'])
config_status = self.config_driver.is_config_delete_complete(
request_data['config_policy_id'], request_data['tenant_id'],
network_function)
except Exception as err:
# REVISIT: May be we need a count before removing the poll event
LOG.error("Error: %(err)s while verifying configuration "
"delete completion.", {'err': err})
self._create_event('USER_CONFIG_DELETE_FAILED',
event_data=request_data, is_internal_event=True)
self._controller.event_complete(event)
return STOP_POLLING
service_profile_id = network_function['service_profile_id']
# Revisit(shabbir): service_type should be passed from previous event
service_type = self._get_service_type(service_profile_id)
if config_status == nfp_constants.ERROR:
self._create_event('USER_CONFIG_DELETE_FAILED',
event_data=request_data, is_internal_event=True)
self._controller.event_complete(event)
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.COMPLETED:
updated_network_function = {'status': nfp_constants.ACTIVE}
LOG.info("Applying user config is successfull moving "
"NF:%(network_function_id)s to ACTIVE",
{'network_function_id':
request_data['network_function_id']})
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
request_data['network_function_id'],
updated_network_function)
operation = event.context['log_context'].get('path')
LOG.info("[Event:Service%(operation)sCompleted]",
{'operation': operation.capitalize()})
LOG.event('Completed %s network function.' % operation,
stats_type=nfp_constants.response_event)
nf_id = request_data['network_function_id']
LOG.event("Sending service updated event to controller.",
type='SERVICE_UPDATED',
nf_id=nf_id,
service_type=service_type)
self._controller.event_complete(event)
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.IN_PROGRESS:
return CONTINUE_POLLING
@nfp_api.poll_event_desc(
event='DELETE_USER_CONFIG_IN_PROGRESS',
spacing=nfp_constants.DELETE_USER_CONFIG_IN_PROGRESS_SPACING)
def check_for_user_config_deleted_fast(self, event):
request_data = event.data
nf_id = request_data['network_function_id']
try:
config_status = self.config_driver.is_config_delete_complete(
request_data['config_policy_id'], request_data['tenant_id'])
except Exception as err:
# REVISIT: May be we need a count before removing the poll event
LOG.error("Error: %(err)s while verifying configuration "
"delete completion.", {'err': err})
# self._create_event('USER_CONFIG_DELETE_FAILED',
# event_data=event_data, is_internal_event=True)
self._controller.event_complete(event)
ducf_event = self._controller.new_event(
id='DELETE_USER_CONFIG',
key=nf_id,
binding_key=nf_id,
desc_dict=request_data['event_desc'])
self._controller.event_complete(ducf_event, result="FAILED")
return STOP_POLLING
if config_status == nfp_constants.ERROR:
# self._create_event('USER_CONFIG_DELETE_FAILED',
# event_data=event_data, is_internal_event=True)
self._controller.event_complete(event)
ducf_event = self._controller.new_event(
id='DELETE_USER_CONFIG',
key=nf_id,
binding_key=nf_id,
desc_dict=request_data['event_desc'])
self._controller.event_complete(ducf_event, result="FAILED")
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.COMPLETED:
self._controller.event_complete(event)
ducf_event = self._controller.new_event(
id='DELETE_USER_CONFIG',
key=nf_id,
binding_key=nf_id,
desc_dict=request_data['event_desc'])
self._controller.event_complete(ducf_event, result="SUCCESS")
return STOP_POLLING
# Trigger RPC to notify the Create_Service caller with status
elif config_status == nfp_constants.IN_PROGRESS:
return CONTINUE_POLLING
def handle_user_config_applied(self, event):
request_data = event.data
network_function = {
'status': nfp_constants.ACTIVE,
'config_policy_id': request_data['config_policy_id']
}
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
request_data['network_function_id'],
network_function)
# Trigger RPC to notify the Create_Service caller with status
def handle_config_applied(self, event):
nfp_context = event.data['nfp_context']
base_mode = nfp_context['base_mode']
network_function_id = event.data['network_function_id']
if base_mode:
network_function = {
'status': nfp_constants.ACTIVE,
}
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
network_function_id,
network_function)
LOG.info("Applying user config is successfull moving "
"NF: %(network_function_id)s to ACTIVE",
{'network_function_id':
network_function_id})
else:
'''
network_function_instance_id = (
event.data['network_function_instance_id'])
if network_function_instance_id:
nfi = {
'status': nfp_constants.ACTIVE,
}
nfi = self.db_handler.update_network_function_instance(
self.db_session, network_function_instance_id, nfi)
'''
event_desc = nfp_context['event_desc']
key = nfp_context['key']
id = nfp_context['id']
# Complete the original event here
event = self._controller.new_event(id=id, key=key,
desc_dict=event_desc)
self._controller.event_complete(event, result='HANDLED')
def handle_update_user_config_failed(self, event):
event_data = event.data
network_function_id = event_data['network_function_id']
LOG.error("NSO: updating user config failed, moving "
"network function %(network_function_id)s to ERROR",
{'network_function_id': network_function_id})
self.handle_user_config_failed(event)
def handle_user_config_failed(self, event):
request_data = event.data
updated_network_function = {
'status': nfp_constants.ERROR,
'config_policy_id': request_data.get('config_policy_id')
}
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
request_data['network_function_id'],
updated_network_function)
# Trigger RPC to notify the Create_Service caller with status
operation = event.context['log_context'].get('path')
LOG.error("[Event:Service%(operation)sFailed]",
{'operation': operation.capitalize()})
LOG.event('%s network function failed.' % operation.capitalize(),
stats_type=nfp_constants.error_event)
def handle_user_config_deleted(self, event):
# DELETE DEVICE_CONFIGURATION is not serialized with DELETE
# SERVICE_CONFIGURATION so,no logic need to be added here.
pass
# Change to Delete_failed or continue with instance and device
# delete if config delete fails? or status CONFIG_DELETE_FAILED ??
def handle_user_config_delete_failed(self, event):
request_data = event.data
updated_network_function = {
'status': nfp_constants.ERROR,
}
# If stack delete fails after successfull heat stack create
# in fw update case
# still we make network function status active to allow subsequent
# sharing
if (request_data.get('operation') in [
'consumer_add', 'consumer_remove', 'update'] and not
self.config_driver.is_update_config_supported(
request_data['service_type'])):
updated_network_function.update({'status': nfp_constants.ACTIVE})
LOG.warning(
"Failed to delete old stack id: %(stack_id)s in"
"firewall update case, Need to manually delete it",
{"stack_id": request_data['config_policy_id']})
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
request_data['network_function_id'],
updated_network_function)
# Trigger RPC to notify the Create_Service caller with status
# When NDO deletes Device DB, the Foreign key NSI will be nulled
# So we have to pass the NSI ID in delete event to NDO and process
# the result based on that
def delete_network_function_db(self, event):
results = event.result
for result in results:
if result.result.lower() != 'success':
LOG.error("Event: %(result_id)s failed",
{'result_id': result.id})
network_function_details = event.context
if not network_function_details['base_mode_support']:
nfi_id = (
network_function_details['network_function_instance']['id'])
with nfp_ctx_mgr.DbContextManager.new(
suppress=(
nfp_exc.NetworkFunctionInstanceNotFound,)):
self.db_handler.delete_network_function_instance(
self.db_session, nfi_id)
nf_id = network_function_details['network_function']['id']
with nfp_ctx_mgr.DbContextManager:
nf = self.db_handler.get_network_function(
self.db_session, nf_id)
if not nf['network_function_instances']:
with nfp_ctx_mgr.DbContextManager:
self.db_handler.delete_network_function(
self.db_session, nf['id'])
LOG.info("[Event:ServiceDeleteCompleted]")
LOG.event("Completed delete network function.",
stats_type=nfp_constants.response_event)
service_type = network_function_details['service_profile'][
'service_type']
LOG.event("Sending service deleted event to controller.",
type='SERVICE_DELETED',
nf_id=nf_id,
service_type=service_type)
LOG.info("Deleted NF:%(nf_id)s ",
{'nf_id': nf['id']})
self._controller.event_complete(event)
def handle_device_deleted(self, event):
request_data = event.data
nfi_id = request_data['network_function_instance_id']
with nfp_ctx_mgr.DbContextManager:
nfi = self.db_handler.get_network_function_instance(
self.db_session, nfi_id)
self.db_handler.delete_network_function_instance(
self.db_session, nfi_id)
network_function = self.db_handler.get_network_function(
self.db_session, nfi['network_function_id'])
nf_id = network_function['id']
if not network_function['network_function_instances']:
with nfp_ctx_mgr.DbContextManager:
self.db_handler.delete_network_function(
self.db_session, nfi['network_function_id'])
LOG.info("[Event:ServiceDeleteCompleted]")
LOG.event("Completed delete network function.",
stats_type=nfp_constants.response_event)
service_type = request_data['service_type']
LOG.event("Sending service deleted event to controller.",
type='SERVICE_DELETED',
nf_id=nf_id,
service_type=service_type)
LOG.info("Deleted NF:%(nf_id)s ",
{'nf_id': nf_id})
# Inform delete service caller with delete completed RPC
def get_network_function(self, context, network_function_id):
try:
nfp_context = module_context.get()
nfp_context['log_context']['meta_id'] = network_function_id
nfp_context['log_context']['auth_token'] = context.auth_token
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session, network_function_id)
return network_function
except nfp_exc.NetworkFunctionNotFound:
LOG.warning("Failed to retrieve Network Function details for"
" %(network_function)s",
{'network_function': network_function_id})
return None
except Exception:
LOG.exception("Failed to retrieve Network Function details for"
" %(network_function)s",
{'network_function': network_function_id})
return None
def get_network_functions(self, context, filters):
with nfp_ctx_mgr.DbContextManager:
return self.db_handler.get_network_functions(
self.db_session, filters)
def _update_network_function_status(self, network_function_id, operation):
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function_id,
{'status': self.status_map[operation]['status'],
'status_description': self.status_map[operation][
'status_description']})
def handle_policy_target_added(self, context, network_function_id,
policy_target):
nfp_context = module_context.get()
nfp_path.update_path(network_function_id)
nfp_context['event_desc']['path_type'] = 'update'
nfp_context['event_desc']['path_key'] = network_function_id
nfp_context['log_context']['path'] = 'update'
nfp_context['log_context']['meta_id'] = network_function_id
nfp_context['log_context']['auth_token'] = context.auth_token
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session, network_function_id)
network_function_details = self.get_network_function_details(
network_function_id)
base_mode_support, _ = self._get_base_mode_support(
network_function['service_profile_id'])
if not base_mode_support:
required_attributes = ["network_function",
"network_function_instance",
"network_function_device"]
else:
required_attributes = ["network_function"]
if (set(required_attributes) & set(network_function_details.keys()) !=
set(required_attributes)):
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
network_function['id'],
{'status': nfp_constants.ERROR,
'status_description': (
"Config Update for Policy Target "
"addition event failed")})
return
self._update_network_function_status(network_function['id'],
operation='pt_add')
service_config = network_function['service_config']
service_type = self._get_service_type(
network_function['service_profile_id'])
network_function_data = {
'network_function_details': network_function_details,
'policy_target': policy_target,
'service_type': service_type
}
self.pt_add_user_config(network_function_data,
service_config)
def policy_target_add_user_config(self, event):
request_data = event.data
network_function_details = self.get_network_function_details(
request_data['network_function_id'])
policy_target = request_data['policy_target']
config_id = self.config_driver.handle_policy_target_operations(
network_function_details, policy_target, "add")
network_function = network_function_details['network_function']
request_data = {
'config_policy_id': config_id,
'tenant_id': network_function['tenant_id'],
'network_function_id': network_function['id'],
'network_function_details': network_function_details
}
if not config_id:
self._controller.event_complete(event)
self._create_event('USER_CONFIG_FAILED',
event_data=request_data, is_internal_event=True)
return
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function['id'],
{'config_policy_id': config_id})
self._controller.event_complete(event)
self._create_event(
'APPLY_USER_CONFIG_IN_PROGRESS',
event_data=request_data,
is_poll_event=True, original_event=event,
max_times=nfp_constants.APPLY_USER_CONFIG_IN_PROGRESS_MAXRETRY)
def handle_policy_target_removed(self, context, network_function_id,
policy_target):
nfp_context = module_context.get()
nfp_path.update_path(network_function_id)
nfp_context['event_desc']['path_type'] = 'update'
nfp_context['event_desc']['path_key'] = network_function_id
nfp_context['log_context']['path'] = 'update'
nfp_context['log_context']['meta_id'] = network_function_id
nfp_context['log_context']['auth_token'] = context.auth_token
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session, network_function_id)
network_function_details = self.get_network_function_details(
network_function_id)
base_mode_support, _ = self._get_base_mode_support(
network_function['service_profile_id'])
if not base_mode_support:
required_attributes = ["network_function",
"network_function_instance",
"network_function_device"]
else:
required_attributes = ["network_function"]
if (set(required_attributes) & set(network_function_details.keys()) !=
set(required_attributes)):
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
network_function['id'],
{'status': nfp_constants.ERROR,
'status_description': (
"Config Update for Policy Target "
"removed event failed")})
return
self._update_network_function_status(network_function['id'],
operation='pt_remove')
service_config = network_function['service_config']
service_type = self._get_service_type(
network_function['service_profile_id'])
network_function_data = {
'network_function_details': network_function_details,
'policy_target': policy_target,
'service_type': service_type
}
self.pt_remove_user_config(network_function_data,
service_config)
def policy_target_remove_user_config(self, event):
request_data = event.data
network_function_details = self.get_network_function_details(
request_data['network_function_id'])
policy_target = request_data['policy_target']
config_id = self.config_driver.handle_policy_target_operations(
network_function_details, policy_target, "remove")
network_function = network_function_details['network_function']
request_data = {
'config_policy_id': config_id,
'tenant_id': network_function['tenant_id'],
'network_function_id': network_function['id'],
'network_function_details': network_function_details
}
if not config_id:
self._controller.event_complete(event)
self._create_event('USER_CONFIG_FAILED',
event_data=request_data, is_internal_event=True)
return
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session, self.db_handler.update_network_function,
network_function['id'],
{'config_policy_id': config_id})
self._controller.event_complete(event)
self._create_event(
'APPLY_USER_CONFIG_IN_PROGRESS',
event_data=request_data,
is_poll_event=True, original_event=event,
max_times=nfp_constants.APPLY_USER_CONFIG_IN_PROGRESS_MAXRETRY)
def handle_consumer_ptg_added(self, context, network_function_id,
consumer_ptg):
nfp_context = module_context.get()
nfp_path.update_path(network_function_id)
nfp_context['event_desc']['path_type'] = 'update'
nfp_context['event_desc']['path_key'] = network_function_id
nfp_context['log_context']['path'] = 'update'
nfp_context['log_context']['meta_id'] = network_function_id
nfp_context['log_context']['auth_token'] = context.auth_token
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session, network_function_id)
network_function_details = self.get_network_function_details(
network_function_id)
base_mode_support, _ = self._get_base_mode_support(
network_function['service_profile_id'])
if not base_mode_support:
required_attributes = ["network_function",
"network_function_instance",
"network_function_device"]
else:
required_attributes = ["network_function"]
if (set(required_attributes) & set(network_function_details.keys()) !=
set(required_attributes)):
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(self.db_session,
self.db_handler.update_network_function,
network_function['id'],
{'status': nfp_constants.ERROR,
'status_description': (
"Config Update for Consumer Policy"
" Target Group Addition failed")})
return
self._update_network_function_status(network_function['id'],
operation='ptg_add')
service_config = network_function['service_config']
service_type = self._get_service_type(
network_function['service_profile_id'])
network_function_data = {
'network_function_details': network_function_details,
'consumer_ptg': consumer_ptg,
'service_type': service_type
}
self.consumer_add_user_config(network_function_data,
service_config)
def consumer_ptg_add_user_config(self, event):
request_data = event.data
network_function_details = self.get_network_function_details(
request_data['network_function_id'])
network_function = network_function_details['network_function']
service_profile_id = network_function['service_profile_id']
service_type = self._get_service_type(service_profile_id)
request_data.update({'service_type': service_type})
self._controller.event_complete(event)
self._create_event('UPDATE_USER_CONFIG_IN_PROGRESS',
event_data=request_data,
is_internal_event=True,
original_event=event)
def handle_consumer_ptg_removed(self, context, network_function_id,
consumer_ptg):
nfp_context = module_context.get()
nfp_path.update_path(network_function_id)
nfp_context['event_desc']['path_type'] = 'update'
nfp_context['event_desc']['path_key'] = network_function_id
nfp_context['log_context']['path'] = 'update'
nfp_context['log_context']['meta_id'] = network_function_id
nfp_context['log_context']['auth_token'] = context.auth_token
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session, network_function_id)
network_function_details = self.get_network_function_details(
network_function_id)
base_mode_support, _ = self._get_base_mode_support(
network_function['service_profile_id'])
if not base_mode_support:
required_attributes = ["network_function",
"network_function_instance",
"network_function_device"]
else:
required_attributes = ["network_function"]
if (set(required_attributes) & set(network_function_details.keys()) !=
set(required_attributes)):
with nfp_ctx_mgr.DbContextManager as dcm:
dcm.lock(
self.db_session,
self.db_handler.update_network_function,
network_function['id'],
{'status': nfp_constants.ERROR,
'status_description': (
"Config Update for Consumer Policy"
" Target Group Removal failed")})
return
self._update_network_function_status(network_function['id'],
operation='ptg_remove')
service_config = network_function['service_config']
service_type = self._get_service_type(
network_function['service_profile_id'])
network_function_data = {
'network_function_details': network_function_details,
'consumer_ptg': consumer_ptg,
'service_type': service_type
}
self.consumer_remove_user_config(network_function_data,
service_config)
def consumer_ptg_remove_user_config(self, event):
request_data = event.data
network_function_details = self.get_network_function_details(
request_data['network_function_id'])
network_function = network_function_details['network_function']
service_profile_id = network_function['service_profile_id']
service_type = self._get_service_type(service_profile_id)
request_data.update({'service_type': service_type})
self._controller.event_complete(event)
self._create_event('UPDATE_USER_CONFIG_IN_PROGRESS',
event_data=request_data,
is_internal_event=True,
original_event=event)
def get_port_info(self, port_id):
try:
with nfp_ctx_mgr.DbContextManager:
port_info = self.db_handler.get_port_info(
self.db_session, port_id)
return port_info
except Exception:
LOG.exception("Failed to retrieve Port Info for"
" %(port_id)s",
{'port_id': port_id})
return None
def get_network_function_details(self, network_function_id):
network_function = None
network_function_instance = None
network_function_device = None
service_type = None
nfp_context = module_context.get()
if nfp_context:
network_function = nfp_context.get('network_function', None)
network_function_instance = nfp_context.get(
'network_function_instance', None)
network_function_device = nfp_context.get(
'network_function_device', None)
service_details = nfp_context.get('service_details', None)
if service_details:
service_type = service_details.get('service_type', None)
if not network_function:
with nfp_ctx_mgr.DbContextManager:
network_function = self.db_handler.get_network_function(
self.db_session, network_function_id)
network_function_details = {
'network_function': network_function,
'service_type': service_type
}
if not network_function_instance:
network_function_instances = network_function[
'network_function_instances']
if not network_function_instances:
return network_function_details
# Assuming single network_function_instance
with nfp_ctx_mgr.DbContextManager:
network_function_instance = (
self.db_handler.get_network_function_instance(
self.db_session, network_function_instances[0]))
network_function_details[
'network_function_instance'] = network_function_instance
if not network_function_device:
if network_function_instance['network_function_device_id']:
with nfp_ctx_mgr.DbContextManager:
network_function_device = (
self.db_handler.get_network_function_device(
self.db_session,
network_function_instance[
'network_function_device_id']))
network_function_details['network_function_device'] = (
network_function_device)
return network_function_details
def get_network_function_context(self, network_function_id):
network_function_details = self.get_network_function_details(
network_function_id)
network_function_device = (
network_function_details['network_function_device'])
ports_info = []
for id in network_function_details[
'network_function_instance']['port_info']:
port_info = self.get_port_info(id)
ports_info.append(port_info)
mngmt_port_info = None
monitor_port_info = None
if network_function_device:
mgmt_port_id = network_function_device['mgmt_port_id']
if mgmt_port_id is not None:
mngmt_port_info = self.get_port_info(mgmt_port_id)
monitor_port_id = network_function_device['monitoring_port_id']
if monitor_port_id is not None:
monitor_port_info = self.get_port_info(monitor_port_id)
nf_context = {'network_function_details': network_function_details,
'ports_info': ports_info,
'mngmt_port_info': mngmt_port_info,
'monitor_port_info': monitor_port_info}
return nf_context
def get_pt_info_for_plumbing(self, chain_info):
plumbing_request = {'management': [], 'provider': [{}],
'consumer': [{}]}
service_type = chain_info['profile']['service_type']
if service_type.lower() in GATEWAY_SERVICES:
plumbing_request['plumbing_type'] = nfp_constants.GATEWAY_TYPE
else:
plumbing_request['plumbing_type'] = nfp_constants.ENDPOINT_TYPE
return plumbing_request
class NSOConfiguratorRpcApi(object):
"""Service Manager side of the Service Manager to Service agent RPC API"""
API_VERSION = '1.0'
target = oslo_messaging.Target(version=API_VERSION)
def __init__(self, context, conf):
super(NSOConfiguratorRpcApi, self).__init__()
self.conf = conf
self.context = context
self.client = n_rpc.get_client(self.target)
self.rpc_api = self.client.prepare(
version=self.API_VERSION,
topic=nfp_rpc_topics.NFP_NSO_CONFIGURATOR_TOPIC)
def _get_request_info(self, user_config_data, operation):
network_function_details = user_config_data[
'network_function_details']
network_function_instance = network_function_details.get(
'network_function_instance')
nfp_context = module_context.get()
rpc_nfp_context = None
if nfp_context:
rpc_nfp_context = {
'event_desc': nfp_context.get('event_desc', None),
'key': nfp_context.pop('key', None),
'id': nfp_context.pop('id', None),
'base_mode': nfp_context.pop('base_mode', None)}
nf_data = {
'service_chain_instance': nfp_context.get(
'service_chain_instance'),
'provider': nfp_context.get('provider'),
'consumer': nfp_context.get('consumer')
}
rpc_nfp_context.update(nf_data)
request_info = {
'nf_id': network_function_details['network_function']['id'],
'nfi_id': (network_function_instance['id']
if network_function_instance else ''),
'nfd_id': None,
'requester': nfp_constants.SERVICE_ORCHESTRATOR,
'operation': operation,
'logging_context': nfp_context['log_context'],
'nfp_context': rpc_nfp_context
}
if operation in ['consumer_add', 'consumer_remove']:
request_info.update({'consumer_ptg': user_config_data[
'consumer_ptg']})
elif operation in ['pt_add', 'pt_remove']:
request_info.update({'policy_target': user_config_data[
'policy_target']})
nfd = network_function_details.get('network_function_device')
if nfd:
request_info['nfd_id'] = network_function_details[
'network_function_device']['id']
nfd_ip = nfd['mgmt_ip_address']
request_info.update({'device_ip': nfd_ip})
return request_info
def _update_params(self, user_config_data, config_params, operation):
request_info = self._get_request_info(user_config_data, operation)
config_params['info']['context'] = request_info
def create_request_structure(self, user_config_data,
service_config, config_tag):
config_params = {
'info': {
'context': None,
'service_type': user_config_data['service_type'].lower(),
'service_vendor': None
},
'config': [{
'resource': nfp_constants.CONFIG_TAG_RESOURCE_MAP[config_tag],
'resource_data': {
'config_string': service_config,
}
}]
}
return config_params
def create_network_function_user_config(self, user_config_data,
service_config, config_tag):
config_params = self.create_request_structure(user_config_data,
service_config,
config_tag)
self._update_params(user_config_data,
config_params, operation='create')
LOG.info("Sending create heat config request to configurator ")
LOG.debug("Sending create heat config request to configurator "
"with config_params = %s",
config_params)
transport.send_request_to_configurator(self.conf,
self.context,
config_params,
'CREATE')
def delete_network_function_user_config(self, user_config_data,
service_config, config_tag):
config_params = self.create_request_structure(user_config_data,
service_config,
config_tag)
self._update_params(user_config_data,
config_params, operation='delete')
LOG.info("Sending delete heat config request to configurator ")
LOG.debug("Sending delete heat config request to configurator "
" with config_params = %s",
config_params)
transport.send_request_to_configurator(self.conf,
self.context,
config_params,
'DELETE')
def update_network_function_user_config(self, user_config_data,
service_config, config_tag):
config_params = self.create_request_structure(user_config_data,
service_config,
config_tag)
self._update_params(user_config_data,
config_params, operation='update')
LOG.info("Sending update heat config request to configurator. ")
transport.send_request_to_configurator(self.conf,
self.context,
config_params,
'UPDATE')
def policy_target_add_user_config(self, user_config_data,
service_config, config_tag):
config_params = self.create_request_structure(user_config_data,
service_config,
config_tag)
self._update_params(user_config_data,
config_params, operation='pt_add')
LOG.info("Sending Policy Target and heat config request to "
"configurator .")
transport.send_request_to_configurator(self.conf,
self.context,
config_params,
'CREATE')
def policy_target_remove_user_config(self, user_config_data,
service_config, config_tag):
config_params = self.create_request_structure(user_config_data,
service_config,
config_tag)
self._update_params(user_config_data,
config_params, operation='pt_remove')
LOG.info("Sending Policy Target remove heat config request to "
"configurator. ")
transport.send_request_to_configurator(self.conf,
self.context,
config_params,
'DELETE')
def consumer_add_user_config(self, user_config_data,
service_config, config_tag):
config_params = self.create_request_structure(user_config_data,
service_config,
config_tag)
self._update_params(user_config_data,
config_params, operation='consumer_add')
LOG.info("Sending consumer and heat config request to "
"configurator .")
transport.send_request_to_configurator(self.conf,
self.context,
config_params,
'CREATE')
def consumer_remove_user_config(self, user_config_data,
service_config, config_tag):
config_params = self.create_request_structure(user_config_data,
service_config,
config_tag)
self._update_params(user_config_data,
config_params, operation='consumer_remove')
LOG.info("Sending consumer remove heat config request to "
"configurator .")
transport.send_request_to_configurator(self.conf,
self.context,
config_params,
'DELETE')
class ExceptionHandler(object):
@staticmethod
def event_method_mapping(event_id):
event_handler_mapping = {
"CREATE_NETWORK_FUNCTION_INSTANCE_DB": (
ExceptionHandler.handle_create_nfi_db_exception),
"CREATE_NETWORK_FUNCTION_INSTANCE": (
ExceptionHandler.handle_create_nfi_exception),
"DEVICE_CREATED": ExceptionHandler.handle_device_created_exception,
"SEND_USER_CONFIG":
ExceptionHandler.handle_send_heat_config_exception,
"APPLY_USER_CONFIG":
ExceptionHandler.handle_apply_user_config_exception,
"APPLY_USER_CONFIG_BASEMODE":
ExceptionHandler.handle_apply_user_config_basemode_exception,
"CHECK_HEAT_CONFIG_RESULT":
ExceptionHandler.handle_check_heat_config_result_exception,
"INITIATE_USER_CONFIG":
ExceptionHandler.handle_initiate_user_config_exception,
"UPDATE_NETWORK_FUNCTION_DESCRIPTION": (
ExceptionHandler.handle_update_nf_description_exception),
"CHECK_USER_CONFIG_COMPLETE": (
ExceptionHandler.handle_check_user_config_complete_exception),
"SERVICE_CONFIGURED": (
ExceptionHandler.handle_service_configured_exception),
"CONFIG_APPLIED": ExceptionHandler.handle_config_applied_exception,
"DEVICE_CREATE_FAILED": (
ExceptionHandler.handle_device_create_failed_exception),
"DELETE_NETWORK_FUNCTION_INSTANCE": (
ExceptionHandler.handle_delete_nfi_exception),
"DELETE_USER_CONFIG": (
ExceptionHandler.handle_delete_user_config_exception),
"DELETE_USER_CONFIG_IN_PROGRESS": (
ExceptionHandler.handle_check_user_config_deleted_exception),
"DELETE_NETWORK_FUNCTION_DB": (
ExceptionHandler.handle_delete_network_function_db_exception),
}
if event_id not in event_handler_mapping:
raise Exception(_("Invalid Event ID"))
else:
return event_handler_mapping[event_id]
@staticmethod
def handle(orchestrator, event, exception):
exc_type, exc_value, exc_traceback = sys.exc_info()
message = "Traceback: %s" % traceback.format_exception(
exc_type, exc_value, exc_traceback)
LOG.error(message)
exception_handler = ExceptionHandler.event_method_mapping(event.id)
return exception_handler(orchestrator, event, exception)
@staticmethod
def handle_create_nfi_db_exception(orchestrator, event, exception):
nfp_context = event.context
network_function = nfp_context['network_function']
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function['id'],
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_create_nfi_exception(orchestrator, event, exception):
nfp_context = event.context
network_function = nfp_context['network_function']
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function['id'],
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_device_created_exception(orchestrator, event, exception):
device = event.data
network_function_id = device['network_function_id']
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function_id,
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_send_heat_config_exception(orchestrator, event, exception):
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_check_heat_config_result_exception(
orchestrator, event, exception):
nfp_context = event.data['nfp_context']
base_mode = nfp_context['base_mode']
if base_mode:
network_function = nfp_context['network_function']
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function['id'],
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
return
event_desc = nfp_context['event_desc']
key = nfp_context['key']
id = nfp_context['id']
# Complete the original event here
ev = orchestrator._controller.new_event(id=id, key=key,
desc_dict=event_desc)
orchestrator._controller.event_complete(ev, result='FAILED')
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_apply_user_config_exception(orchestrator, event, exception):
nfp_context = event.context
network_function = nfp_context['network_function']
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = orchestrator._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
orchestrator._controller.event_complete(
apply_config_event, result='FAILED')
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_apply_user_config_basemode_exception(
orchestrator, event, exception):
nfp_context = event.data
network_function = nfp_context['network_function']
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function['id'],
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_initiate_user_config_exception(orchestrator, event, exception):
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_update_nf_description_exception(orchestrator, event, exception):
nfp_context = event.context
network_function = nfp_context['network_function']
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = orchestrator._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
orchestrator._controller.event_complete(
apply_config_event, result='FAILED')
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_check_user_config_complete_exception(
orchestrator, event, exception):
nfp_context = event.context
network_function = nfp_context['network_function']
event_desc = nfp_context.pop('event_desc', None)
apply_config_event = orchestrator._controller.new_event(
id='INITIATE_USER_CONFIG',
key=network_function['id'],
desc_dict=event_desc)
orchestrator._controller.event_complete(
apply_config_event, result='FAILED')
orchestrator._controller.event_complete(event, result='FAILED')
return {'poll': False}
@staticmethod
def handle_service_configured_exception(orchestrator, event, exception):
nfp_context = event.context
network_function = nfp_context['network_function']
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function['id'],
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_config_applied_exception(orchestrator, event, exception):
nfp_context = event.data['nfp_context']
network_function = nfp_context['network_function']
base_mode = nfp_context['base_mode']
if base_mode:
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function['id'],
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
return
event_desc = nfp_context['event_desc']
key = nfp_context['key']
id = nfp_context['id']
ev = orchestrator._controller.new_event(id=id, key=key,
desc_dict=event_desc)
orchestrator._controller.event_complete(ev, result='FAILED')
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_device_create_failed_exception(orchestrator, event, exception):
request_data = event.data
network_function_id = request_data['network_function_id']
orchestrator.db_handler.update_network_function(
orchestrator.db_session,
network_function_id,
{'status': nfp_constants.ERROR})
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_delete_nfi_exception(orchestrator, event, exception):
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_delete_user_config_exception(orchestrator, event, exception):
orchestrator._controller.event_complete(event, result='FAILED')
@staticmethod
def handle_check_user_config_deleted_exception(
orchestrator, event, exception):
request_data = event.data
nf_id = request_data['network_function_id']
orchestrator._controller.event_complete(event, result='FAILED')
ducf_event = orchestrator._controller.new_event(
id='DELETE_USER_CONFIG',
key=nf_id,
binding_key=nf_id,
desc_dict=request_data['event_desc'])
orchestrator._controller.event_complete(ducf_event, result="FAILED")
return {"poll": False}
@staticmethod
def handle_delete_network_function_db_exception(
orchestrator, event, exception):
orchestrator._controller.event_complete(event, result='FAILED')