From 2e02eaca05d36a5df666c8abe558f003a7c0d9b6 Mon Sep 17 00:00:00 2001 From: AkashDeep Date: Mon, 30 May 2016 20:13:42 +0530 Subject: [PATCH 01/17] latency changes --- .../nfp/configurator/agents/generic_config.py | 16 +- gbpservice/nfp/core/context.py | 40 +++ .../coal/networking/nfp_gbp_network_driver.py | 8 +- .../networking/nfp_neutron_network_driver.py | 19 + .../config_drivers/heat_driver.py | 332 ++++++++++++++++-- .../drivers/orchestration_driver.py | 104 +++++- .../modules/device_orchestrator.py | 178 +++++++++- .../modules/service_orchestrator.py | 150 ++++++-- 8 files changed, 773 insertions(+), 74 deletions(-) create mode 100644 gbpservice/nfp/core/context.py diff --git a/gbpservice/nfp/configurator/agents/generic_config.py b/gbpservice/nfp/configurator/agents/generic_config.py index 7c6c53f899..199d4c0c63 100644 --- a/gbpservice/nfp/configurator/agents/generic_config.py +++ b/gbpservice/nfp/configurator/agents/generic_config.py @@ -21,6 +21,9 @@ from gbpservice.nfp.core import event as nfp_event from gbpservice.nfp.core import poll as nfp_poll +STOP_POLLING = {'poll': False} +CONTINUE_POLLING = {'poll': True} + LOG = nfp_logging.getLogger(__name__) """Implements APIs invoked by configurator for processing RPC messages. @@ -268,8 +271,9 @@ def _process_event(self, ev): if (resource_data.get('periodicity') == gen_cfg_const.INITIAL and result == common_const.SUCCESS): notification_data = self._prepare_notification_data(ev, result) - self.sc.poll_event_done(ev) + # self.sc.poll_event_done(ev) self.notify._notification(notification_data) + return STOP_POLLING elif resource_data.get('periodicity') == gen_cfg_const.FOREVER: if result == common_const.FAILED: """If health monitoring fails continuously for 5 times @@ -282,8 +286,9 @@ def _process_event(self, ev): notification_data = self._prepare_notification_data( ev, result) - self.sc.poll_event_done(ev) + # self.sc.poll_event_done(ev) self.notify._notification(notification_data) + return STOP_POLLING elif result == common_const.SUCCESS: """set fail_count to 0 if it had failed earlier even once """ @@ -293,8 +298,9 @@ def _process_event(self, ev): that particular service vm's health monitor """ notification_data = self._prepare_notification_data(ev, result) - self.sc.poll_event_done(ev) + # self.sc.poll_event_done(ev) self.notify._notification(notification_data) + return STOP_POLLING else: """For other events, irrespective of result send notification""" notification_data = self._prepare_notification_data(ev, result) @@ -357,7 +363,7 @@ def poll_event_cancel(self, ev): @nfp_poll.poll_event_desc( event=gen_cfg_const.EVENT_CONFIGURE_HEALTHMONITOR, - spacing=5) + spacing=2) def handle_configure_healthmonitor(self, ev): """Decorator method called for poll event CONFIGURE_HEALTHMONITOR Finally it Enqueues response into notification queue. @@ -367,7 +373,7 @@ def handle_configure_healthmonitor(self, ev): Returns: None """ - self._process_event(ev) + return self._process_event(ev) def events_init(sc, drivers, rpcmgr): diff --git a/gbpservice/nfp/core/context.py b/gbpservice/nfp/core/context.py new file mode 100644 index 0000000000..8dc3337ad0 --- /dev/null +++ b/gbpservice/nfp/core/context.py @@ -0,0 +1,40 @@ +# 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. + +import threading + +nfp_context_store = threading.local() + +class NfpContext(object): + def __init__(self, **kwargs): + self.admin_token = kwargs.get('admin_token', None) + self.tenant_tokens = kwargs.get('tenant_tokens', None) + self.nfp_device_data = kwargs.get('nfp_device_data', None) + self.nfp_service_data = kwargs.get('nfp_service_data', None) + + def to_dict(self): + return {'admin_token': self.admin_token, + 'tenant_tokens': self.tenant_tokens, + 'nfp_device_data': self.nfp_device_data, + 'nfp_service_data': self.nfp_service_data} + +def store_nfp_context(**kwargs): + nfp_context_store.context = NfpContext(**kwargs) + +def clear_nfp_context(): + nfp_context_store.context = None + +def get_nfp_context(): + context = getattr(nfp_context_store, 'context', None) + if context: + return context.to_dict() + return {} diff --git a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py index ca00982b7b..a2861815d6 100644 --- a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py +++ b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py @@ -15,7 +15,6 @@ nfp_neutron_network_driver as neutron_nd ) - class NFPGBPNetworkDriver(neutron_nd.NFPNeutronNetworkDriver): def __init__(self, config): self.config = config @@ -42,6 +41,13 @@ def update_port(self, token, port_id, port): port) return pt['port_id'] + def get_neutron_port_details(self, token, port_id): + self.network_handler = openstack_driver.NeutronClient(self.config) + port_details = super(NFPGBPNetworkDriver, self).get_port_and_subnet_details( + token, port_id) + self.network_handler = openstack_driver.GBPClient(self.config) + return port_details + def get_port_details(self, token, port_id): _port_id = self.get_port_id(token, port_id) self.network_handler = openstack_driver.NeutronClient(self.config) diff --git a/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py b/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py index 0ee00dcf84..d18ce93e2b 100644 --- a/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py +++ b/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py @@ -38,6 +38,25 @@ def update_port(self, token, port_id, port): port = self.network_handler.update_port(token, port_id, port) return port['port'] + #[<--PERF] + def get_port_and_subnet_details(self, token, port_id): + port = self.network_handler.get_port(token, port_id) + + # ip + ip = port['port']['fixed_ips'][0]['ip_address'] + + # mac + mac = port['port']['mac_address'] + + # gateway ip + subnet_id = port['port']['fixed_ips'][0]['subnet_id'] + subnet = self.network_handler.get_subnet(token, subnet_id) + cidr = subnet['subnet']['cidr'] + gateway_ip = subnet['subnet']['gateway_ip'] + + return (ip, mac, cidr, gateway_ip, port, subnet) + #[-->PERF] + def get_port_details(self, token, port_id): port = self.network_handler.get_port(token, port_id) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index 7d4e92f704..13d3066405 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -43,6 +43,8 @@ from gbpservice.nfp.core import log as nfp_logging +from gbpservice.nfp.core import context as nfp_core_context + HEAT_DRIVER_OPTS = [ cfg.StrOpt('svc_management_ptg_name', default='svc_management_ptg', @@ -96,6 +98,16 @@ def __init__(self, config): self.neutron_client = NeutronClient(config) # self.resource_owner_tenant_id = None + #[<--PERF] + keystone_conf = cfg.CONF.keystone_authtoken + keystone_version = keystone_conf.auth_version + self.v2client = self.keystoneclient._get_v2_keystone_admin_client() + self.admin_id = self.v2client.users.find(name=keystone_conf.admin_user).id + self.admin_role = self._get_role_by_name(self.v2client, "admin", keystone_version) + self.heat_role = self._get_role_by_name(self.v2client, "heat_stack_owner", keystone_version) + #[-->PERF] + + ''' @property def resource_owner_tenant_id(self): @@ -128,12 +140,17 @@ def _resource_owner_tenant_id(self): def _get_resource_owner_context(self): if cfg.CONF.heat_driver.is_service_admin_owned: - tenant_id = self._resource_owner_tenant_id() + #[<--PERF] + tenant_id = None + # tenant_id = self._resource_owner_tenant_id() user, pwd, tenant_name, auth_url =\ self.keystoneclient.get_keystone_creds() auth_token = self.keystoneclient.get_scoped_keystone_token( user, pwd, tenant_name, tenant_id) - return auth_token, tenant_id + + tenant_id = self.keystoneclient.get_tenant_id(auth_token, tenant_name) + #[-->PERF] + return auth_token, tenant_id def _get_role_by_name(self, keystone_client, name, keystone_version): if keystone_version == 'v2.0': @@ -155,11 +172,25 @@ def get_allocated_roles(self, v2client, user, tenant_id=None): allocated_role_names.append(role.name) return allocated_role_names + def _assign_admin_user_to_project_v2(self, project_id): + allocated_role_names = self.get_allocated_roles(self.v2client, self.admin_id, project_id) + if self.admin_role: + if self.admin_role.name not in allocated_role_names: + self.v2client.roles.add_user_role( + self.admin_id, self.admin_role.id, tenant=project_id) + if self.heat_role: + if self.heat_role.name not in allocated_role_names: + self.v2client.roles.add_user_role(self.admin_id, self.heat_role.id, + tenant=project_id) + def _assign_admin_user_to_project(self, project_id): keystone_conf = cfg.CONF.keystone_authtoken keystone_version = keystone_conf.auth_version if keystone_version == 'v2.0': + #[<--PERF] + return self._assign_admin_user_to_project_v2(project_id) + ''' v2client = self.keystoneclient._get_v2_keystone_admin_client() admin_id = v2client.users.find(name=keystone_conf.admin_user).id admin_role = self._get_role_by_name(v2client, "admin", @@ -178,6 +209,8 @@ def _assign_admin_user_to_project(self, project_id): if heat_role.name not in allocated_role_names: v2client.roles.add_user_role(admin_id, heat_role.id, tenant=project_id) + ''' + #[-->PERF] else: v3client = self.keystoneclient._get_v3_keystone_admin_client() admin_id = v3client.users.find(name=keystone_conf.admin_user).id @@ -200,13 +233,15 @@ def keystone(self, user, pwd, tenant_name, tenant_id=None): return self.keystoneclient.get_scoped_keystone_token( user, pwd, tenant_name) - def _get_heat_client(self, resource_owner_tenant_id, tenant_id=None): + def _get_heat_client(self, resource_owner_tenant_id, tenant_id=None, assign_admin=False): user_tenant_id = tenant_id or resource_owner_tenant_id - try: - self._assign_admin_user_to_project(user_tenant_id) - except Exception: - LOG.exception(_LE("Failed to assign admin user to project")) - return None + if assign_admin: + try: + self._assign_admin_user_to_project(user_tenant_id) + except Exception: + LOG.exception(_LE("Failed to assign admin user to project")) + return None + user, password, tenant, auth_url =\ self.keystoneclient.get_keystone_creds() admin_token = self.keystone( @@ -445,6 +480,54 @@ def _get_all_heat_resource_keys(self, template_resource_dict, resource_keys.append(key) return resource_keys + def _create_firewall_template(self, auth_token, service_details, stack_template): + consumer = service_details['consumer_ptg'] + provider = service_details['provider_ptg'] + + _, consumer_eps = self._get_consumers_for_chain(auth_token, provider) + + if (consumer is None) and (consumer_eps is None): + return None + + is_template_aws_version = stack_template.get( + 'AWSTemplateFormatVersion', False) + resources_key = 'Resources' if is_template_aws_version else 'resources' + properties_key = ('Properties' if is_template_aws_version + else 'properties') + fw_rule_keys = self._get_all_heat_resource_keys( + stack_template[resources_key], is_template_aws_version, + 'OS::Neutron::FirewallRule') + fw_policy_key = self._get_all_heat_resource_keys( + stack_template['resources'], is_template_aws_version, + 'OS::Neutron::FirewallPolicy')[0] + + provider_cidr = service_details['provider_cidr'] + + fw_template_properties = dict( + resources_key=resources_key, properties_key=properties_key, + is_template_aws_version=is_template_aws_version, + fw_rule_keys=fw_rule_keys, + fw_policy_key=fw_policy_key) + + consumer_cidr = service_details['consumer_cidr'] + self._append_firewall_rule(stack_template, provider_cidr, consumer_cidr, fw_template_properties, consumer['id']) + + for consumer_ep in consumer_eps_details: + fw_template_properties.update({'name': consumer_ep[:3]}) + self._append_firewall_rule(stack_template, provider_cidr, + "0.0.0.0/0", fw_template_properties, + consumer_ep) + + for rule_key in fw_rule_keys: + del stack_template[resources_key][rule_key] + stack_template[resources_key][fw_policy_key][ + properties_key]['firewall_rules'].remove( + {'get_resource': rule_key}) + + return stack_template + + + def _update_firewall_template(self, auth_token, provider, stack_template): consumer_ptgs, consumer_eps = self._get_consumers_for_chain( auth_token, provider) @@ -606,11 +689,131 @@ def _get_site_conn_keys(self, template_resource_dict, keys.append(key) return keys + def _update_node_config_create(self, auth_token, tenant_id, service_chain_node, service_chain_instance, + provider, provider_port, consumer, consumer_port, network_function, + mgmt_ip, service_details): + + nf_desc = None + common_desc = {'network_function_id': network_function['id']} + + service_type = service_details['service_details']['service_type'] + service_vendor = service_details['service_details']['service_vendor'] + device_type = service_details['service_details']['device_type'] + base_mode_support = (True if device_type == 'None' + else False) + + + _, stack_template_str = self.parse_template_config_string( + service_chain_node.get('config')) + try: + stack_template = (jsonutils.loads(stack_template_str) if + stack_template_str.startswith('{') else + yaml.load(stack_template_str)) + except Exception: + LOG.error(_LE( + "Unable to load stack template for service chain " + "node: %(node_id)s") % {'node_id': service_chain_node}) + return None, None + config_param_values = service_chain_instance.get( + 'config_param_values', '{}') + stack_params = {} + try: + config_param_values = jsonutils.loads(config_param_values) + except Exception: + LOG.error(_LE("Unable to load config parameters")) + return None, None + + is_template_aws_version = stack_template.get( + 'AWSTemplateFormatVersion', False) + resources_key = ('Resources' if is_template_aws_version + else 'resources') + parameters_key = ('Parameters' if is_template_aws_version + else 'parameters') + properties_key = ('Properties' if is_template_aws_version + else 'properties') + + if not base_mode_support: + provider_port_mac = provider_port['mac_address'] + provider_cidr = service_details['provider_subnet']['cidr'] + provider_subnet = service_details['provider_subnet'] + else: + provider_port_mac = '' + provider_cidr = '' + standby_provider_port_mac = None + + if service_type == pconst.LOADBALANCER: + self._generate_pool_members( + auth_token, stack_template, config_param_values, + provider, is_template_aws_version) + config_param_values['Subnet'] = provider_subnet['id'] + config_param_values['service_chain_metadata'] = "" + if not base_mode_support: + config_param_values[ + 'service_chain_metadata'] = str(common_desc) + nf_desc = str((SC_METADATA % (service_chain_instance['id'], + mgmt_ip, + provider_port_mac, + standby_provider_port_mac, + network_function['id'], + service_vendor))) + + lb_pool_key = self._get_heat_resource_key( + stack_template[resources_key], + is_template_aws_version, + 'OS::Neutron::Pool') + stack_template[resources_key][lb_pool_key][properties_key][ + 'description'] = str(common_desc) + elif service_type == pconst.FIREWALL: + stack_template = self._create_firewall_template(auth_token, service_details, stack_template) + + if not stack_template: + return None, None + self._modify_fw_resources_name( + stack_template, provider, is_template_aws_version) + if not base_mode_support: + firewall_desc = {'vm_management_ip': mgmt_ip, + 'provider_ptg_info': [provider_port_mac], + 'provider_cidr': provider_cidr, + 'service_vendor': service_vendor, + 'network_function_id': network_function[ + 'id']} + + fw_key = self._get_heat_resource_key( + stack_template[resources_key], + is_template_aws_version, + 'OS::Neutron::Firewall') + stack_template[resources_key][fw_key][properties_key][ + 'description'] = str(common_desc) + + nf_desc = str(firewall_desc) + + if nf_desc: + network_function['description'] = network_function[ + 'description'] + '\n' + nf_desc + + for parameter in stack_template.get(parameters_key) or []: + if parameter in config_param_values: + stack_params[parameter] = config_param_values[parameter] + + LOG.info(_LI('Final stack_template : %(stack_data)s, ' + 'stack_params : %(params)s') % + {'stack_data': stack_template, 'params': stack_params}) + return (stack_template, stack_params) + + + + + def _update_node_config(self, auth_token, tenant_id, service_profile, service_chain_node, service_chain_instance, provider, consumer_port, network_function, provider_port, update=False, mgmt_ip=None, - consumer=None): + consumer=None, service_details=None): + + if not update: + return self._update_node_config_create(auth_token, tenant_id, service_chain_node, service_chain_instance, + provider, provider_port, consumer, consumer_port, network_function, mgmt_ip, service_details) + nf_desc = None common_desc = {'network_function_id': network_function['id']} provider_cidr = provider_subnet = None @@ -855,7 +1058,78 @@ def parse_template_config_string(self, config_str): tag_str = nfp_constants.HEAT_CONFIG_TAG return tag_str, service_config + def get_service_details_from_cache(self, nfp_context, network_function_details): + network_function = network_function_details['network_function'] + network_function_instance = network_function_details.get('network_function_instance') + service_details = nfp_context['nfp_service_data']['service_details'] + if service_details['device_type'] != 'None': + network_function_device = network_function_details[ + 'network_function_device'] + mgmt_ip = network_function_device['mgmt_ip_address'] + else: + mgmt_ip = None + + admin_token = self.keystoneclient.get_admin_token() + heat_stack_id = network_function['heat_stack_id'] + service_id = network_function['service_id'] + servicechain_node = self.gbp_client.get_servicechain_node(admin_token, + service_id) + service_chain_id = network_function['service_chain_id'] + servicechain_instance = self.gbp_client.get_servicechain_instance( + admin_token, + service_chain_id) + + if network_function_instance: + for port_info in network_function_instance.get('port_info'): + port_classification = None + if port_info['port_model'] == nfp_constants.GBP_PORT: + port_classification = port_info['port_classification'] + port_id = port_info['port_id'] + else: + port_id = port_info['id'] + + if port_classification == nfp_constants.CONSUMER: + consumer_port = port_info['neutron_info']['port'] + consumer_subnet = port_info['neutron_info']['subnet'] + consumer_policy_target_group = None + + elif port_classification == nfp_constants.PROVIDER: + LOG.info(_LI("provider info: %s") % (port_id)) + provider_port = port_info['neutron_info']['port'] + provider_subnet = port_info['neutron_info']['subnet'] + provider_policy_target_group = None + + policy_target = self.gbp_client.get_policy_target( + admin_token, policy_target_id) + provider_policy_target_group = self.gbp_client.get_policy_target_group( + admin_token, + policy_target['policy_target_group_id']) + + + + return { + 'service_profile': None, + 'service_details': service_details, + 'servicechain_node': servicechain_node, + 'servicechain_instance': servicechain_instance, + 'consumer_port': consumer_port, + 'consumer_subnet': consumer_subnet, + 'provider_port': provider_port, + 'provider_subnet': provider_subnet, + 'mgmt_ip': mgmt_ip, + 'heat_stack_id': heat_stack_id, + 'provider_ptg': provider_policy_target_group, + 'consumer_ptg': consumer_policy_target_group + } + + def get_service_details(self, network_function_details): + #[<--PERF] + nfp_context = nfp_core_context.get_nfp_context() + if nfp_context: + return self.get_service_details_from_cache(nfp_context, network_function_details) + + db_handler = nfp_db.NFPDbBase() db_session = nfp_db_api.get_session() network_function = network_function_details['network_function'] @@ -1036,14 +1310,21 @@ def _wait_for_stack_operation_complete(self, heatclient, stack_id, action, return None def is_config_complete(self, stack_id, tenant_id, - network_function_details): + network_function_details, heat_client=None): + + #[<--PERF] + nfp_context = nfp_core_context.get_nfp_context() + #[-->PERF] + success_status = "COMPLETED" failure_status = "ERROR" intermediate_status = "IN_PROGRESS" - auth_token, resource_owner_tenant_id =\ - self._get_resource_owner_context() - heatclient = self._get_heat_client(resource_owner_tenant_id, - tenant_id=tenant_id) + + if not heat_client: + auth_token, resource_owner_tenant_id =\ + self._get_resource_owner_context() + heatclient = self._get_heat_client(resource_owner_tenant_id, + tenant_id=tenant_id) if not heatclient: return failure_status try: @@ -1051,7 +1332,12 @@ def is_config_complete(self, stack_id, tenant_id, if stack.stack_status == 'DELETE_FAILED': return failure_status elif stack.stack_status == 'CREATE_COMPLETE': - self.loadbalancer_post_stack_create(network_function_details) + if nfp_context: + service_type = nfp_context['nfp_service_data']['service_details']['service_type'] + if service_type.lower() == pconst.LOADBALANCER.lower(): + self.loadbalancer_post_stack_create(network_function_details) + else: + self.loadbalancer_post_stack_create(network_function_details) return success_status elif stack.stack_status == 'UPDATE_COMPLETE': return success_status @@ -1110,21 +1396,25 @@ def apply_config(self, network_function_details): service_profile = service_details['service_profile'] service_chain_node = service_details['servicechain_node'] service_chain_instance = service_details['servicechain_instance'] - provider = service_details['policy_target_group'] provider = service_details['provider_ptg'] consumer = service_details['consumer_ptg'] consumer_port = service_details['consumer_port'] provider_port = service_details['provider_port'] mgmt_ip = service_details['mgmt_ip'] - service_details = transport.parse_service_flavor_string( - service_profile['service_flavor']) + if service_profile: + service_details = transport.parse_service_flavor_string( + service_profile['service_flavor']) + else: + service_details = service_details['service_details'] auth_token, resource_owner_tenant_id =\ self._get_resource_owner_context() + provider_tenant_id = provider['tenant_id'] heatclient = self._get_heat_client(resource_owner_tenant_id, - tenant_id=provider_tenant_id) + tenant_id=provider_tenant_id, assign_admin=True) + if not heatclient: return None stack_name = ("stack_" + service_chain_instance['name'] + @@ -1138,7 +1428,7 @@ def apply_config(self, network_function_details): auth_token, provider_tenant_id, service_profile, service_chain_node, service_chain_instance, provider, consumer_port, network_function_details['network_function'], - provider_port, mgmt_ip=mgmt_ip, consumer=consumer) + provider_port, mgmt_ip=mgmt_ip, consumer=consumer, service_details=service_details) if not stack_template and not stack_params: return None @@ -1159,7 +1449,7 @@ def apply_config(self, network_function_details): {'stack_id': stack_id, 'stack_name': stack_name, 'provider': provider['id']}) - return stack_id + return stack_id, heat_client def delete_config(self, stack_id, tenant_id): auth_token, resource_owner_tenant_id =\ diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index f3dcdee59b..e4ac9faeb5 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -27,6 +27,9 @@ import operator from gbpservice.nfp.core import log as nfp_logging + +from gbpservice.nfp.core import context as nfp_core_context + LOG = nfp_logging.getLogger(__name__) @@ -158,6 +161,9 @@ def _create_management_interface(self, device_data, network_handler=None): name=name) return {'id': mgmt_interface['id'], + #[<--PERF] + 'port_id': mgmt_interface['port_id'], + #[PERF-->] 'port_model': (nfp_constants.GBP_PORT if device_data['service_details'][ 'network_mode'] == @@ -348,10 +354,14 @@ def get_network_function_device_sharing_info(self, device_data): ): raise exceptions.IncompleteData() + #[<--PERF] + ''' image_name = self._get_image_name(device_data) if image_name: self._update_vendor_data(device_data, device_data.get('token')) + ''' + #[PERF-->] if not self._is_device_sharing_supported(): return None return { @@ -524,8 +534,13 @@ def create_network_function_device(self, device_data, advance_sharing_interfaces = [] try: for interface in interfaces: + #[<--PERF] + ''' port_id = network_handler.get_port_id(token, interface['id']) - interfaces_to_attach.append({'port': port_id}) + interfaces_to_attach.append({'port': port_id})\ + ''' + interfaces_to_attach.append({'port': interface.pop('port_id')}) + #[PERF-->] if not self.supports_hotplug: if self.setup_mode.get(nfp_constants.NEUTRON_MODE): @@ -596,14 +611,30 @@ def create_network_function_device(self, device_data, self._increment_stats_counter('instances') mgmt_ip_address = None + mgmt_neutron_port_info = {} try: for interface in interfaces: if interface['port_classification'] == ( nfp_constants.MANAGEMENT): + #[<--PERF] + (mgmt_ip_address, + mgmt_mac, mgmt_cidr, gateway_ip, + mgmt_port, mgmt_subnet) = network_handler.get_neutron_port_details(token, interface['port_id']) + + mgmt_neutron_port_info = {'neutron_port': mgmt_port, + 'neutron_subnet': mgmt_subnet, + 'ip_address': mgmt_ip_address, + 'mac': mgmt_mac, + 'cidr': mgmt_cidr, + 'gateway_ip': gateway_ip} + ''' (mgmt_ip_address, dummy, dummy, dummy) = network_handler.get_port_details( - token, interface['id']) + -token, interface['id']) + ''' + #[-->PERF] + break except Exception as e: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get management port details. ' @@ -632,6 +663,7 @@ def create_network_function_device(self, device_data, 'name': instance_name, 'mgmt_ip_address': mgmt_ip_address, 'mgmt_port_id': interfaces[0], + 'mgmt_neutron_port_info': mgmt_neutron_port_info, 'max_interfaces': self.maximum_interfaces, 'interfaces_in_use': len(interfaces_to_attach), 'advance_sharing_interfaces': advance_sharing_interfaces, @@ -818,9 +850,14 @@ def plug_network_function_device_interfaces(self, device_data, if not token: return None + #[<--PERF] + #This is already done in "create_network_function_device method of this class. + ''' image_name = self._get_image_name(device_data) if image_name: self._update_vendor_data(device_data) + ''' + #[-->PERF] update_ifaces = [] try: @@ -866,6 +903,10 @@ def plug_network_function_device_interfaces(self, device_data, port['id']) port_id = network_handler.get_port_id(token, port['id']) + #[<--PERF] + # Saving the neutron port id for the gbp pt + port['port_id'] = port_id + #[-->PERF] self.compute_handler_nova.attach_interface( token, self._get_admin_tenant_id(token=token), @@ -883,6 +924,10 @@ def plug_network_function_device_interfaces(self, device_data, port['id']) port_id = network_handler.get_port_id(token, port['id']) + #[<--PERF] + # Saving the neutron port id for the gbp pt + port['port_id'] = port_id + #[-->PERF] self.compute_handler_nova.attach_interface( token, self._get_admin_tenant_id(token=token), @@ -1104,6 +1149,41 @@ def get_network_function_device_healthcheck_info(self, device_data): ] } + @_set_network_handler + def get_network_function_device_port_info(self, device_data, network_handler=None): + if ( + type(device_data['ports']) is not list or + + any(key not in port + for port in device_data['ports'] + for key in ['id', + 'port_classification', + 'port_model']) + ): + raise exceptions.IncompleteData() + + token = self._get_token(device_data.get('token')) + if not token: + return None + + for port in device_data['ports']: + try: + (ip, mac, cidr, gateway_ip, + port, subnet) = ( + network_handler.get_neutron_port_details(token, port['port_id']) + ) + port['neutron_info'] = {'ip': provider_ip, + 'mac': provider_mac, + 'cidr': provider_cidr, + 'gateway_ip': provider_gateway_ip, + 'port': provider_port, + 'subnet': provider_subnet} + except Exception: + self._increment_stats_counter('port_details_get_failures') + LOG.error(_LE('Failed to get provider port details' + ' for get device config info operation')) + return None + @_set_network_handler def get_network_function_device_config_info(self, device_data, network_handler=None): @@ -1163,6 +1243,7 @@ def get_network_function_device_config_info(self, device_data, provider_ip = None provider_mac = None provider_cidr = None + provider_gateway_ip = None consumer_ip = None consumer_mac = None consumer_cidr = None @@ -1171,9 +1252,17 @@ def get_network_function_device_config_info(self, device_data, for port in device_data['ports']: if port['port_classification'] == nfp_constants.PROVIDER: try: + #[<--PERF] + ''' (provider_ip, provider_mac, provider_cidr, dummy) = ( network_handler.get_port_details(token, port['id']) ) + ''' + provider_ip = port['ip'] + provider_mac = port['mac'] + provider_cidr = port['cidr'] + provider_gateway_ip = port['gateway_ip'] + #[-->PERF] except Exception: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get provider port details' @@ -1181,10 +1270,18 @@ def get_network_function_device_config_info(self, device_data, return None elif port['port_classification'] == nfp_constants.CONSUMER: try: + #[<--PERF] + ''' (consumer_ip, consumer_mac, consumer_cidr, consumer_gateway_ip) = ( network_handler.get_port_details(token, port['id']) ) + ''' + consumer_ip = port['ip'] + consumer_mac = port['mac'] + consumer_cidr = port['cidr'] + consumer_gateway_ip = port['gateway_ip'] + except Exception: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get consumer port details' @@ -1205,7 +1302,8 @@ def get_network_function_device_config_info(self, device_data, 'stitching_interface_index': 3, 'provider_mac': provider_mac, 'stitching_mac': consumer_mac, - } + }, + }, { 'resource': nfp_constants.ROUTES_RESOURCE, diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index 0f5d6f7634..8a3faac0f3 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -32,6 +32,8 @@ import traceback from gbpservice.nfp.core import log as nfp_logging +from gbpservice.nfp.core import context as nfp_core_context + LOG = nfp_logging.getLogger(__name__) STOP_POLLING = {'poll': False} @@ -118,6 +120,14 @@ def network_function_notification(self, context, notification_data): logging_context = request_info.get('logging_context') nfp_logging.store_logging_context(**logging_context) + #[<--PERF] + try: + nfp_context = request_info['nfp_context'] + nfp_context['admin_token'] = None + except KeyError: + request_info['nfp_context'] = None + #[-->PERF] + for response in responses: resource = response.get('resource') data = response.get('data') @@ -221,7 +231,8 @@ def event_method_mapping(self, event_id): "CREATE_NETWORK_FUNCTION_DEVICE": ( self.create_network_function_device), "DEVICE_UP": self.perform_health_check, - "DEVICE_HEALTHY": self.plug_interfaces, + "PLUG_INTERFACES": self.plug_interfaces, + "DEVICE_HEALTHY": self.device_healthy, "CONFIGURE_DEVICE": self.create_device_configuration, "DEVICE_CONFIGURED": self.device_configuration_complete, @@ -409,9 +420,14 @@ def _create_network_function_device_db(self, device_info, state): device_info['interfaces_in_use'] = 0 device = self.nsf_db.create_network_function_device(self.db_session, device_info) + #[<--PERF] + #Dont need this here. + ''' mgmt_port_id = device.pop('mgmt_port_id') mgmt_port_id = self._get_port(mgmt_port_id) device['mgmt_port_id'] = mgmt_port_id + ''' + #[-->PERF] if advance_sharing_interfaces: self._create_advance_sharing_interfaces(device, @@ -449,7 +465,7 @@ def _decrement_device_ref_count(self, device): def _increment_device_interface_count(self, device): device['interfaces_in_use'] += len(device['ports']) - self._update_network_function_device_db(device, device['status']) + # self._update_network_function_device_db(device, device['status']) def _decrement_device_interface_count(self, device): device['interfaces_in_use'] -= len(device['ports']) @@ -470,6 +486,15 @@ def _get_device_to_reuse(self, device_data, dev_sharing_info): return device def _get_device_data(self, nfd_request): + #[<--PERF] + # Check if the context already has device_data + context = nfp_core_context.get_nfp_context() + if context['nfp_device_data']: + device_data = context['nfp_device_data'] + return device_data + #[PERF -->] + + device_data = {} network_function = nfd_request.get('network_function') network_function_instance = nfd_request['network_function_instance'] @@ -489,10 +514,17 @@ def _get_device_data(self, nfd_request): network_function_instance['id']) device_data['tenant_id'] = network_function_instance['tenant_id'] + #[<--PERF] + #Are we getting anything more than what is in network_function_instance['port_info'] ? + #Looks like not really. + ''' nsi_port_info = [] for port_id in network_function_instance.pop('port_info'): port_info = self.nsf_db.get_port_info(self.db_session, port_id) nsi_port_info.append(port_info) + ''' + nsi_port_info = network_function_instance['port_info'] + #[PERF -->] device_data['ports'] = nsi_port_info @@ -504,6 +536,13 @@ def _get_device_data(self, nfd_request): device_data['service_details']['network_mode'] = ( nfp_constants.NEUTRON_MODE) device_data['service_vendor'] = service_details['service_vendor'] + + #[<--PERF] + #Store the updated context + context['nfp_device_data'] = device_data + nfp_core_context.store_nfp_context(**context) + #[PERF-->] + return device_data def _get_nsf_db_resource(self, resource_name, resource_id): @@ -521,6 +560,14 @@ def create_network_function_device(self, event): This method either returns existing device which could be reused for a new service or it creates new device instance """ + + #[<--PERF] + # Since this is not internal event, read the context from event + # and store in the current thread. + nfp_context = event.data['nfp_context'] + nfp_core_context.store_nfp_context(**nfp_context) + #[PERF -->] + nfd_request = event.data device = None @@ -562,41 +609,75 @@ def create_network_function_device(self, event): is_internal_event=True) return None + #[<--PERF] + for port in device['ports']: + if port['port_classification'] == nfp_constants.MANAGEMENT: + port['neutron_info'] = driver_device_info['mgmt_neutron_port_info'] + break + #[-->PERF] + # Update newly created device with required params device = self._update_device_data(driver_device_info, device_data) device['network_function_device_id'] = device['id'] # Create DB entry with status as DEVICE_SPAWNING - self._create_network_function_device_db(device, + network_function_device = self._create_network_function_device_db(device, 'DEVICE_SPAWNING') + + #[<--PERF] + device['network_function_device'] = network_function_device + nfp_context = nfp_core_context.get_nfp_context() + nfp_context['nfp_device_data'].update(device) + #[-->PERF] + # Create an event to NSO, to give device_id device_created_data = { 'network_function_instance_id': ( nfd_request['network_function_instance']['id']), - 'network_function_device_id': device['id'] + 'network_function_device_id': device['id'], } - self._create_event(event_id='DEVICE_CREATED', - event_data=device_created_data) self._create_event(event_id='DEVICE_SPAWNING', - event_data=device, + event_data=nfp_context, is_poll_event=True, original_event=event) + self._create_event(event_id='DEVICE_CREATED', + event_data=device_created_data) - @poll_event_desc(event='DEVICE_SPAWNING', spacing=20) + @poll_event_desc(event='DEVICE_SPAWNING', spacing=2) def check_device_is_up(self, event): - device = event.data + + #[<--PERF] + nfp_context = event.data + device = nfp_context['nfp_device_data'] + # device = event.data + #[-->PERF] orchestration_driver = self._get_orchestration_driver( device['service_details']['service_vendor']) is_device_up = ( orchestration_driver.get_network_function_device_status(device)) if is_device_up == nfp_constants.ACTIVE: + #[<--PERF] + # Optimized the db update across three function calls + ''' + self._update_network_function_device_db(device, + 'DEVICE_UP') + ''' + + orchestration_driver.get_network_function_device_port_info(device) + # create event DEVICE_UP self._create_event(event_id='DEVICE_UP', - event_data=device, + event_data=nfp_context, is_internal_event=True) - self._update_network_function_device_db(device, - 'DEVICE_UP') + #[<--PERF] + self._create_event(event_id='PLUG_INTERFACES', + event_data=nfp_context, + is_internal_event=True) + + self._update_network_function_device_db(device, 'HEALTH_CHECK_PENDING') + #[-->PERF] + return STOP_POLLING elif is_device_up == nfp_constants.ERROR: # create event DEVICE_NOT_UP @@ -611,6 +692,11 @@ def check_device_is_up(self, event): return CONTINUE_POLLING def perform_health_check(self, event): + #[<--PERF] + nfp_context = event.data + device = nfp_context['nfp_device_data'] + #[-->PERF] + # The driver tells which protocol / port to monitor ?? device = event.data orchestration_driver = self._get_orchestration_driver( @@ -628,8 +714,15 @@ def perform_health_check(self, event): LOG.debug("Health Check RPC sent to configurator for device: " "%s with health check parameters: %s" % ( device['id'], hm_req)) + #[<--PERF] + #Dont need to update in DB Here as the next function call for plug interfaces + #will update the db. + device['status'] = 'HEALTH_CHECK_PENDING' + ''' self._update_network_function_device_db(device, 'HEALTH_CHECK_PENDING') + ''' + #[-->PERF] def _get_service_type(self, service_profile_id): admin_token = self.keystoneclient.get_admin_token() @@ -678,8 +771,39 @@ def _prepare_device_data(self, device_info): device['advance_sharing_interfaces'] = ( self._get_advance_sharing_interfaces(device['id'])) return device + + #[<--PERF] + def device_healthy(self, event): + nfp_context = event.data['nfp_context'] + device = nfp_context['nfp_device_data'] + self._update_network_function_device_db(device, 'HEALTH_CHECK_COMPLETED') + self._create_event(event_id='DEVICE_ACTIVE', event_data=nfp_context) + self._create_event(event_id='CONFIGURE_DEVICE', + event_data=nfp_context, is_internal_event=True) + #[-->PERF] def plug_interfaces(self, event, is_event_call=True): + + #[-->PERF] + # Now, this event is happening in paralell with HEALTHMONITORING, + # so, we should not generate CONFIGURE_DEVICE & should not update + # DB with HEALTH_CHECK_COMPLETED. + nfp_context = event.data + device = nfp_context['nfp_device_data'] + orchestration_driver = self._get_orchestration_driver( + device['service_details']['service_vendor']) + + _ifaces_plugged_in, advance_sharing_ifaces = ( + orchestration_driver.plug_network_function_device_interfaces( + device)) + if _ifaces_plugged_in: + if advance_sharing_ifaces: + self._update_advance_sharing_interfaces( + device, + advance_sharing_ifaces) + self._increment_device_interface_count(device) + + ''' if is_event_call: device_info = event.data else: @@ -708,8 +832,15 @@ def plug_interfaces(self, event, is_event_call=True): self._create_event(event_id='DEVICE_CONFIGURATION_FAILED', event_data=device, is_internal_event=True) + ''' def create_device_configuration(self, event): + #[<--PERF] + nfp_context = event.data + nfp_core_context.store_nfp_context(nfp_context) + device = nfp_context['nfp_device_data'] + #[-->PERF] + device = event.data orchestration_driver = self._get_orchestration_driver( device['service_details']['service_vendor']) @@ -726,8 +857,13 @@ def create_device_configuration(self, event): device, config_params) def device_configuration_complete(self, event): - device_info = event.data - device = self._prepare_device_data(device_info) + #[<--PERF] + nfp_context = event.data['nfp_context'] + # device_info = event.data + # device = self._prepare_device_data(device_info) + device = nfp_context['nfp_device_data'] + #[-->PERF] + # Change status to active in DB and generate an event DEVICE_ACTIVE # to inform NSO self._increment_device_ref_count(device) @@ -737,16 +873,22 @@ def device_configuration_complete(self, event): "reference count for %(device)s"), {'device_id': device['id'], 'device': device}) + #[<--PERF] + # DEVICE_ACTIVE event is sent paralell to configure device + # so dont need to send here. + ''' device_created_data = { 'network_function_id': ( device['network_function_id']), 'network_function_instance_id': ( device['network_function_instance_id']), - 'network_function_device_id': device['id'] + 'network_function_device_id': device['id'], } # DEVICE_ACTIVE event for NSO. self._create_event(event_id='DEVICE_ACTIVE', event_data=device_created_data) + ''' + #[-->PERF] # Delete path def delete_network_function_device(self, event): @@ -928,7 +1070,11 @@ def _get_request_info(self, device, operation): 'nfd_id': device['id'], 'requester': nfp_constants.DEVICE_ORCHESTRATOR, 'operation': operation, - 'logging_context': nfp_logging.get_logging_context() + 'logging_context': nfp_logging.get_logging_context(), + #[<--PERF] + #Add so that notifications can work on cached data + 'nfp_context': nfp_core_context.get_nfp_context() + #[-->PERF] } nfd_ip = device['mgmt_ip_address'] request_info.update({'device_ip': nfd_ip}) diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 3dd9b325a6..52072968cd 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -32,6 +32,8 @@ import traceback from gbpservice.nfp.core import log as nfp_logging +from gbpservice.nfp.core import context as nfp_core_context + LOG = nfp_logging.getLogger(__name__) STOP_POLLING = {'poll': False} @@ -279,6 +281,15 @@ def network_function_notification(self, context, notification_data): nfp_logging.store_logging_context(**logging_context) serialize = False + #[<--PERF] + try: + nfp_context = request_info['nfp_context'] + nfp_context['admin_token'] = None + except KeyError: + request_info['nfp_context'] = None + #[-->PERF] + + for response in responses: resource = response.get('resource') data = response.get('data') @@ -519,9 +530,11 @@ def update_network_function_user_config(self, network_function_id, if tag_str != nfp_constants.CONFIG_INIT_TAG: network_function_details = self.get_network_function_details( network_function_id) - service_type = self._get_service_type( - network_function_details['network_function'][ - 'service_profile_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 @@ -674,6 +687,17 @@ def create_network_function(self, context, network_function_info): 'share_existing_device': False # Extend service profile if needed } + #[<--PERF] + nfp_context = {} + nfp_context['nfp_service_data'] = create_network_function_instance_request + nfp_context['nfp_service_data']['network_function_info'] = network_function_info + nfp_context['admin_token'] = admin_token + # Save this context in thread - as "CREATE_NETWORK_FUNCTION_INSTANCE" is internal event" + nfp_core_context.store_nfp_context(**nfp_context) + ##[PERF-->] + + + # Create and event to perform Network service instance self._create_event('CREATE_NETWORK_FUNCTION_INSTANCE', event_data=create_network_function_instance_request, @@ -751,7 +775,13 @@ def delete_user_config(self, event): is_poll_event=True, original_event=event) def create_network_function_instance(self, event): - request_data = event.data + #[<--PERF] + #Get from the thread context + nfp_context = nfp_core_context.get_nfp_context() + request_data = nfp_context + # request_data = event.data + #[PERF-->] + name = '%s_%s' % (request_data['network_function']['name'], request_data['network_function']['id']) create_nfi_request = { @@ -784,6 +814,19 @@ def create_network_function_instance(self, event): 'service_details': request_data['service_details'], 'share_existing_device': request_data['share_existing_device'], } + + #[<--PERF] + nfp_context['nfp_service_data'].update({'port_info': request_data['network_function_port_info']}) + nfp_context['nfp_service_data'].update({'network_function_instance': nfp_db}) + + # Update the thread context + nfp_core_context.store_nfp_context(**nfp_context) + + # Since the CREATE_NETWORK_FUNCTION_DEVICE is not internal event + # Update the context in event. + create_nfd_request['nfp_context'] = nfp_context + #[PERF -->] + LOG.info(_LI("[Event:CreateService]")) self._create_event('CREATE_NETWORK_FUNCTION_DEVICE', event_data=create_nfd_request) @@ -799,7 +842,11 @@ def handle_device_created(self, event): return def handle_device_active(self, event): - request_data = event.data + #[<--PERF] + nfp_context = event.nfp_context + nfp_core_context.store_nfp_context(nfp_context) + request_data = nfp_context['nfp_device_data'] + # request_data = event.data nfi = { 'status': nfp_constants.ACTIVE, 'network_function_device_id': request_data[ @@ -807,18 +854,29 @@ def handle_device_active(self, event): } 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']) + ''' + request_data['nfp_device_data']['network_function_instance']['status'] = nfp_constants.ACTIVE + request_data['nfp_device_data']['network_function_instance']['network_function_device_id'] = request_data[ + 'network_function_device_id'] + network_function = nfp_context['nfp_service_data']['network_function'] service_config = network_function['service_config'] self.create_network_function_user_config(network_function['id'], service_config) def apply_user_config(self, event): + #[<--PERF] + nfp_context = event.data['nfp_context'] + nfp_core_context.store_nfp_context(nfp_context) + #[-->PERF] + request_data = event.data network_function_details = self.get_network_function_details( request_data['network_function_id']) - request_data['heat_stack_id'] = self.config_driver.apply_config( + request_data['heat_stack_id'], heat_client = 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'] @@ -828,16 +886,22 @@ def apply_user_config(self, event): return request_data['tenant_id'] = network_function['tenant_id'] request_data['network_function_details'] = network_function_details + LOG.debug("handle_device_active heat_stack_id: %s" % (request_data['heat_stack_id'])) - self.db_handler.update_network_function( - self.db_session, network_function['id'], - {'heat_stack_id': request_data['heat_stack_id'], - 'description': network_function['description']}) + #[<--PERF] + request_data['nfp_context'] = nfp_context + request_data['heat_client'] = heat_client + nfp_context['nfp_service_data']['network_function'].update({'heat_stack_id': request_data['heat_stack_id'], + 'description': network_function['description']}) self._create_event('APPLY_USER_CONFIG_IN_PROGRESS', event_data=request_data, is_poll_event=True, original_event=event) + self.db_handler.update_network_function( + self.db_session, network_function['id'], + {'heat_stack_id': request_data['heat_stack_id'], + 'description': network_function['description']}) def handle_update_user_config(self, event): request_data = event.data @@ -1003,9 +1067,15 @@ def _validate_create_service_input(self, context, create_service_request): def check_for_user_config_complete(self, event): request_data = event.data + + #[<--PERF] + nfp_context = request_data['nfp_context'] + nfp_core_context.store_nfp_context(nfp_context) + #[-->PERF] + config_status = self.config_driver.is_config_complete( request_data['heat_stack_id'], request_data['tenant_id'], - request_data['network_function_details']) + request_data['network_function_details'], heat_client=request_data['heat_client']) if config_status == nfp_constants.ERROR: LOG.info(_LI("NSO: applying user config failed for " "network function %(network_function_id)s data " @@ -1477,24 +1547,47 @@ def get_port_info(self, port_id): return None def get_network_function_details(self, network_function_id): - network_function = self.db_handler.get_network_function( - self.db_session, network_function_id) + #[<--PERF] + network_function = None + network_function_instance = None + network_function_device = None + service_type = None + + nfp_context = nfp_core_context.get_nfp_context() + if nfp_context and nfp_context['nfp_service_data']: + network_function = nfp_context['nfp_service_data']['network_function'] + network_function_instance = nfp_context['nfp_service_data']['network_function_instance'] + if nfp_context['nfp_device_data']: + network_function_device = nfp_context['nfp_device_data']['network_function_device'] + service_type = nfp_context['nfp_service_data']['service_details']['service_type'] + + if not network_function: + network_function = self.db_handler.get_network_function( + self.db_session, network_function_id) + network_function_details = { - 'network_function': network_function + 'network_function': network_function, + 'service_type': service_type } - network_function_instances = network_function[ - 'network_function_instances'] - if not network_function_instances: - return network_function_details - nfi = self.db_handler.get_network_function_instance( - self.db_session, network_function_instances[0]) - network_function_details['network_function_instance'] = nfi - if nfi['network_function_device_id']: - network_function_device = ( - self.db_handler.get_network_function_device( - self.db_session, nfi['network_function_device_id'])) - network_function_details['network_function_device'] = ( - network_function_device) + + if not network_function_instance: + network_function_instances = network_function[ + 'network_function_instances'] + if not network_function_instances: + return network_function_details + 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']: + network_function_device = ( + self.db_handler.get_network_function_device( + self.db_session, nfi['network_function_device_id'])) + network_function_details['network_function_device'] = ( + network_function_device) + #[-->PERF] return network_function_details @@ -1525,7 +1618,8 @@ def _get_request_info(self, user_config_data, operation): 'nfd_id': None, 'requester': nfp_constants.SERVICE_ORCHESTRATOR, 'operation': operation, - 'logging_context': nfp_logging.get_logging_context() + 'logging_context': nfp_logging.get_logging_context(), + 'nfp_context': nfp_core_context.get_nfp_context() } if operation in ['consumer_add', 'consumer_remove']: request_info.update({'consumer_ptg': user_config_data[ From ea35531eda7d622d74075ee46720e450d7654ff2 Mon Sep 17 00:00:00 2001 From: AkashDeep Date: Tue, 31 May 2016 01:39:37 +0530 Subject: [PATCH 02/17] changes while testing --- .../config_drivers/heat_driver.py | 45 +++++++---- .../drivers/orchestration_driver.py | 78 +++++++++++-------- .../modules/device_orchestrator.py | 52 +++++++------ .../modules/service_orchestrator.py | 25 +++--- 4 files changed, 117 insertions(+), 83 deletions(-) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index 13d3066405..19cfc7bd43 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -501,7 +501,7 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) stack_template['resources'], is_template_aws_version, 'OS::Neutron::FirewallPolicy')[0] - provider_cidr = service_details['provider_cidr'] + provider_cidr = service_details['provider_subnet']['cidr'] fw_template_properties = dict( resources_key=resources_key, properties_key=properties_key, @@ -509,10 +509,9 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) fw_rule_keys=fw_rule_keys, fw_policy_key=fw_policy_key) - consumer_cidr = service_details['consumer_cidr'] + consumer_cidr = service_details['consumer_subnet']['cidr'] self._append_firewall_rule(stack_template, provider_cidr, consumer_cidr, fw_template_properties, consumer['id']) - - for consumer_ep in consumer_eps_details: + for consumer_ep in consumer_eps: fw_template_properties.update({'name': consumer_ep[:3]}) self._append_firewall_rule(stack_template, provider_cidr, "0.0.0.0/0", fw_template_properties, @@ -1079,10 +1078,13 @@ def get_service_details_from_cache(self, nfp_context, network_function_details): admin_token, service_chain_id) + nfp_device_data = nfp_context['nfp_device_data'] if network_function_instance: - for port_info in network_function_instance.get('port_info'): + # for port_info in network_function_instance.get('port_info'): + for port_info in nfp_device_data.get('ports'): port_classification = None if port_info['port_model'] == nfp_constants.GBP_PORT: + policy_target_id = port_info['id'] port_classification = port_info['port_classification'] port_id = port_info['port_id'] else: @@ -1091,7 +1093,9 @@ def get_service_details_from_cache(self, nfp_context, network_function_details): if port_classification == nfp_constants.CONSUMER: consumer_port = port_info['neutron_info']['port'] consumer_subnet = port_info['neutron_info']['subnet'] - consumer_policy_target_group = None + policy_target = self.gbp_client.get_policy_target( + admin_token, policy_target_id) + consumer_policy_target_group = {'id': policy_target['policy_target_group_id']} elif port_classification == nfp_constants.PROVIDER: LOG.info(_LI("provider info: %s") % (port_id)) @@ -1310,7 +1314,7 @@ def _wait_for_stack_operation_complete(self, heatclient, stack_id, action, return None def is_config_complete(self, stack_id, tenant_id, - network_function_details, heat_client=None): + network_function_details, heatclient=None): #[<--PERF] nfp_context = nfp_core_context.get_nfp_context() @@ -1320,11 +1324,28 @@ def is_config_complete(self, stack_id, tenant_id, failure_status = "ERROR" intermediate_status = "IN_PROGRESS" - if not heat_client: + if not heatclient: auth_token, resource_owner_tenant_id =\ self._get_resource_owner_context() - heatclient = self._get_heat_client(resource_owner_tenant_id, - tenant_id=tenant_id) + timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) + if timeout_seconds: + timeout_mins = timeout_mins + 1 + user, password, tenant, auth_url =\ + self.keystoneclient.get_keystone_creds() + try: + heatclient = HeatClient( + user, + resource_owner_tenant_id, + cfg.CONF.heat_driver.heat_uri, + password, + auth_token=auth_token, + timeout_mins=timeout_mins) + except Exception: + LOG.exception(_LE("Failed to create heatclient object")) + return None + + #heatclient = self._get_heat_client(resource_owner_tenant_id, + # tenant_id=tenant_id) if not heatclient: return failure_status try: @@ -1405,8 +1426,6 @@ def apply_config(self, network_function_details): if service_profile: service_details = transport.parse_service_flavor_string( service_profile['service_flavor']) - else: - service_details = service_details['service_details'] auth_token, resource_owner_tenant_id =\ self._get_resource_owner_context() @@ -1449,7 +1468,7 @@ def apply_config(self, network_function_details): {'stack_id': stack_id, 'stack_name': stack_name, 'provider': provider['id']}) - return stack_id, heat_client + return stack_id, heatclient def delete_config(self, stack_id, tenant_id): auth_token, resource_owner_tenant_id =\ diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index e4ac9faeb5..2a2be4fc64 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -539,7 +539,7 @@ def create_network_function_device(self, device_data, port_id = network_handler.get_port_id(token, interface['id']) interfaces_to_attach.append({'port': port_id})\ ''' - interfaces_to_attach.append({'port': interface.pop('port_id')}) + interfaces_to_attach.append({'port': interface['port_id']}) #[PERF-->] if not self.supports_hotplug: @@ -1151,6 +1151,7 @@ def get_network_function_device_healthcheck_info(self, device_data): @_set_network_handler def get_network_function_device_port_info(self, device_data, network_handler=None): + LOG.error("########## DEVICE DATA: %s" %(str(device_data))) if ( type(device_data['ports']) is not list or @@ -1166,27 +1167,32 @@ def get_network_function_device_port_info(self, device_data, network_handler=Non if not token: return None - for port in device_data['ports']: + new_device_ports = [] + for device_port in device_data['ports']: try: (ip, mac, cidr, gateway_ip, port, subnet) = ( - network_handler.get_neutron_port_details(token, port['port_id']) + network_handler.get_neutron_port_details(token, device_port['port_id']) ) - port['neutron_info'] = {'ip': provider_ip, - 'mac': provider_mac, - 'cidr': provider_cidr, - 'gateway_ip': provider_gateway_ip, - 'port': provider_port, - 'subnet': provider_subnet} - except Exception: + device_port['neutron_info'] = {'ip': ip, + 'mac': mac, + 'cidr': cidr, + 'gateway_ip': gateway_ip, + 'port': port['port'], + 'subnet': subnet['subnet']} + new_device_ports.append(device_port) + except Exception as e: self._increment_stats_counter('port_details_get_failures') - LOG.error(_LE('Failed to get provider port details' + LOG.error(_LE('@@@@@@ Failed to get provider port details' ' for get device config info operation')) + raise e return None + device_data['ports'] = new_device_ports + @_set_network_handler def get_network_function_device_config_info(self, device_data, - network_handler=None): + network_handler=None, is_create_request=False): """ Get the configuration information for NFD :param device_data: NFD @@ -1249,43 +1255,47 @@ def get_network_function_device_config_info(self, device_data, consumer_cidr = None consumer_gateway_ip = None + LOG.error("!!!!!!!!!!!!!!!!! DEVICE DATA: %s" %(str(device_data))) + for port in device_data['ports']: if port['port_classification'] == nfp_constants.PROVIDER: try: #[<--PERF] - ''' - (provider_ip, provider_mac, provider_cidr, dummy) = ( - network_handler.get_port_details(token, port['id']) - ) - ''' - provider_ip = port['ip'] - provider_mac = port['mac'] - provider_cidr = port['cidr'] - provider_gateway_ip = port['gateway_ip'] + if not is_create_request: + (provider_ip, provider_mac, provider_cidr, dummy) = ( + network_handler.get_port_details(token, port['id']) + ) + else: + provider_ip = port['neutron_info']['ip'] + provider_mac = port['neutron_info']['mac'] + provider_cidr = port['neutron_info']['cidr'] + provider_gateway_ip = port['neutron_info']['gateway_ip'] #[-->PERF] - except Exception: + except Exception as e: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get provider port details' ' for get device config info operation')) + raise e return None elif port['port_classification'] == nfp_constants.CONSUMER: try: #[<--PERF] - ''' - (consumer_ip, consumer_mac, consumer_cidr, - consumer_gateway_ip) = ( - network_handler.get_port_details(token, port['id']) - ) - ''' - consumer_ip = port['ip'] - consumer_mac = port['mac'] - consumer_cidr = port['cidr'] - consumer_gateway_ip = port['gateway_ip'] - - except Exception: + if not is_create_request: + (consumer_ip, consumer_mac, consumer_cidr, + consumer_gateway_ip) = ( + network_handler.get_port_details(token, port['id']) + ) + else: + consumer_ip = port['neutron_info']['ip'] + consumer_mac = port['neutron_info']['mac'] + consumer_cidr = port['neutron_info']['cidr'] + consumer_gateway_ip = port['neutron_info']['gateway_ip'] + + except Exception as e: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get consumer port details' ' for get device config info operation')) + raise e return None return { diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index 8a3faac0f3..d86c225c7e 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -485,11 +485,11 @@ def _get_device_to_reuse(self, device_data, dev_sharing_info): device_data) return device - def _get_device_data(self, nfd_request): + def _get_device_data(self, nfd_request, is_create_request=False): #[<--PERF] # Check if the context already has device_data context = nfp_core_context.get_nfp_context() - if context['nfp_device_data']: + if context != {} and context['nfp_device_data']: device_data = context['nfp_device_data'] return device_data #[PERF -->] @@ -517,13 +517,13 @@ def _get_device_data(self, nfd_request): #[<--PERF] #Are we getting anything more than what is in network_function_instance['port_info'] ? #Looks like not really. - ''' - nsi_port_info = [] - for port_id in network_function_instance.pop('port_info'): - port_info = self.nsf_db.get_port_info(self.db_session, port_id) - nsi_port_info.append(port_info) - ''' - nsi_port_info = network_function_instance['port_info'] + if is_create_request: + nsi_port_info = network_function_instance['port_info'] + else: + nsi_port_info = [] + for port_id in network_function_instance.pop('port_info'): + port_info = self.nsf_db.get_port_info(self.db_session, port_id) + nsi_port_info.append(port_info) #[PERF -->] device_data['ports'] = nsi_port_info @@ -539,8 +539,9 @@ def _get_device_data(self, nfd_request): #[<--PERF] #Store the updated context - context['nfp_device_data'] = device_data - nfp_core_context.store_nfp_context(**context) + if is_create_request: + context['nfp_device_data'] = device_data + nfp_core_context.store_nfp_context(**context) #[PERF-->] return device_data @@ -575,7 +576,7 @@ def create_network_function_device(self, event): "device request with data %(data)s"), {'data': nfd_request}) - device_data = self._get_device_data(nfd_request) + device_data = self._get_device_data(nfd_request, is_create_request=True) orchestration_driver = self._get_orchestration_driver( device_data['service_details']['service_vendor']) dev_sharing_info = ( @@ -609,6 +610,10 @@ def create_network_function_device(self, event): is_internal_event=True) return None + # Update newly created device with required params + device = self._update_device_data(driver_device_info, device_data) + device['network_function_device_id'] = device['id'] + #[<--PERF] for port in device['ports']: if port['port_classification'] == nfp_constants.MANAGEMENT: @@ -616,10 +621,6 @@ def create_network_function_device(self, event): break #[-->PERF] - # Update newly created device with required params - device = self._update_device_data(driver_device_info, device_data) - device['network_function_device_id'] = device['id'] - # Create DB entry with status as DEVICE_SPAWNING network_function_device = self._create_network_function_device_db(device, 'DEVICE_SPAWNING') @@ -664,16 +665,18 @@ def check_device_is_up(self, event): 'DEVICE_UP') ''' + #[<--PERF] + self._create_event(event_id='PLUG_INTERFACES', + event_data=nfp_context, + is_internal_event=True) + + LOG.error("$$$$$$$$ %s" %(str(device))) orchestration_driver.get_network_function_device_port_info(device) # create event DEVICE_UP self._create_event(event_id='DEVICE_UP', event_data=nfp_context, is_internal_event=True) - #[<--PERF] - self._create_event(event_id='PLUG_INTERFACES', - event_data=nfp_context, - is_internal_event=True) self._update_network_function_device_db(device, 'HEALTH_CHECK_PENDING') #[-->PERF] @@ -694,11 +697,12 @@ def check_device_is_up(self, event): def perform_health_check(self, event): #[<--PERF] nfp_context = event.data + nfp_core_context.store_nfp_context(**nfp_context) + # device = event.data device = nfp_context['nfp_device_data'] #[-->PERF] # The driver tells which protocol / port to monitor ?? - device = event.data orchestration_driver = self._get_orchestration_driver( device['service_details']['service_vendor']) hm_req = ( @@ -837,16 +841,16 @@ def plug_interfaces(self, event, is_event_call=True): def create_device_configuration(self, event): #[<--PERF] nfp_context = event.data - nfp_core_context.store_nfp_context(nfp_context) + nfp_core_context.store_nfp_context(**nfp_context) + # device = event.data device = nfp_context['nfp_device_data'] #[-->PERF] - device = event.data orchestration_driver = self._get_orchestration_driver( device['service_details']['service_vendor']) config_params = ( orchestration_driver.get_network_function_device_config_info( - device)) + device, is_create_request=True)) if not config_params: self._create_event(event_id='DRIVER_ERROR', event_data=device, diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 52072968cd..414a551b80 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -778,7 +778,7 @@ def create_network_function_instance(self, event): #[<--PERF] #Get from the thread context nfp_context = nfp_core_context.get_nfp_context() - request_data = nfp_context + request_data = nfp_context['nfp_service_data'] # request_data = event.data #[PERF-->] @@ -816,8 +816,9 @@ def create_network_function_instance(self, event): } #[<--PERF] + nfi_db['port_info'] = request_data['network_function_port_info'] nfp_context['nfp_service_data'].update({'port_info': request_data['network_function_port_info']}) - nfp_context['nfp_service_data'].update({'network_function_instance': nfp_db}) + nfp_context['nfp_service_data'].update({'network_function_instance': nfi_db}) # Update the thread context nfp_core_context.store_nfp_context(**nfp_context) @@ -843,8 +844,8 @@ def handle_device_created(self, event): def handle_device_active(self, event): #[<--PERF] - nfp_context = event.nfp_context - nfp_core_context.store_nfp_context(nfp_context) + nfp_context = event.data + nfp_core_context.store_nfp_context(**nfp_context) request_data = nfp_context['nfp_device_data'] # request_data = event.data nfi = { @@ -858,8 +859,8 @@ def handle_device_active(self, event): network_function = self.db_handler.get_network_function( self.db_session, nfi['network_function_id']) ''' - request_data['nfp_device_data']['network_function_instance']['status'] = nfp_constants.ACTIVE - request_data['nfp_device_data']['network_function_instance']['network_function_device_id'] = request_data[ + nfp_context['nfp_service_data']['network_function_instance']['status'] = nfp_constants.ACTIVE + nfp_context['nfp_service_data']['network_function_instance']['network_function_device_id'] = request_data[ 'network_function_device_id'] network_function = nfp_context['nfp_service_data']['network_function'] service_config = network_function['service_config'] @@ -870,7 +871,7 @@ def handle_device_active(self, event): def apply_user_config(self, event): #[<--PERF] nfp_context = event.data['nfp_context'] - nfp_core_context.store_nfp_context(nfp_context) + nfp_core_context.store_nfp_context(**nfp_context) #[-->PERF] request_data = event.data @@ -891,7 +892,7 @@ def apply_user_config(self, event): % (request_data['heat_stack_id'])) #[<--PERF] request_data['nfp_context'] = nfp_context - request_data['heat_client'] = heat_client + # request_data['heat_client'] = heat_client nfp_context['nfp_service_data']['network_function'].update({'heat_stack_id': request_data['heat_stack_id'], 'description': network_function['description']}) self._create_event('APPLY_USER_CONFIG_IN_PROGRESS', @@ -1070,12 +1071,12 @@ def check_for_user_config_complete(self, event): #[<--PERF] nfp_context = request_data['nfp_context'] - nfp_core_context.store_nfp_context(nfp_context) + nfp_core_context.store_nfp_context(**nfp_context) #[-->PERF] config_status = self.config_driver.is_config_complete( request_data['heat_stack_id'], request_data['tenant_id'], - request_data['network_function_details'], heat_client=request_data['heat_client']) + request_data['network_function_details']) if config_status == nfp_constants.ERROR: LOG.info(_LI("NSO: applying user config failed for " "network function %(network_function_id)s data " @@ -1554,7 +1555,7 @@ def get_network_function_details(self, network_function_id): service_type = None nfp_context = nfp_core_context.get_nfp_context() - if nfp_context and nfp_context['nfp_service_data']: + if nfp_context !={} and nfp_context['nfp_service_data']: network_function = nfp_context['nfp_service_data']['network_function'] network_function_instance = nfp_context['nfp_service_data']['network_function_instance'] if nfp_context['nfp_device_data']: @@ -1584,7 +1585,7 @@ def get_network_function_details(self, network_function_id): if network_function_instance['network_function_device_id']: network_function_device = ( self.db_handler.get_network_function_device( - self.db_session, nfi['network_function_device_id'])) + self.db_session, network_function_instance['network_function_device_id'])) network_function_details['network_function_device'] = ( network_function_device) #[-->PERF] From 6a245c4a8886cc6d508bac4b5fa9fe1cd03d854d Mon Sep 17 00:00:00 2001 From: AkashDeep Date: Thu, 2 Jun 2016 16:32:13 +0530 Subject: [PATCH 03/17] changes while testing --- .../ncp/node_drivers/nfp_node_driver.py | 105 ++++- gbpservice/nfp/bin/nfp_orch_agent.ini | 2 +- gbpservice/nfp/bin/nfp_proxy_agent.ini | 2 +- gbpservice/nfp/bin/proxy.ini | 3 +- .../agent/otc_service_events.py | 2 +- gbpservice/nfp/core/context.py | 22 +- gbpservice/nfp/lib/RestClientOverUnix.py | 3 +- gbpservice/nfp/lib/transport.py | 2 + .../coal/networking/nfp_gbp_network_driver.py | 6 + .../config_drivers/heat_driver.py | 303 ++++++++++----- gbpservice/nfp/orchestrator/db/nfp_db.py | 6 +- .../drivers/orchestration_driver.py | 366 +++++++++++++----- .../modules/device_orchestrator.py | 220 ++++++++--- .../modules/service_orchestrator.py | 181 +++++---- .../openstack/openstack_driver.py | 8 + gbpservice/nfp/proxy_agent/proxy/proxy.py | 8 +- 16 files changed, 894 insertions(+), 345 deletions(-) diff --git a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py index bf48502647..66a0ef58fe 100644 --- a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py +++ b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py @@ -38,6 +38,8 @@ from gbpservice.nfp.common import constants as nfp_constants from gbpservice.nfp.common import topics as nfp_rpc_topics +from gbpservice.nfp.core import threadpool as core_tp + NFP_NODE_DRIVER_OPTS = [ cfg.BoolOpt('is_service_admin_owned', @@ -59,7 +61,7 @@ LOG = logging.getLogger(__name__) - +thread_pool = core_tp.ThreadPool() class InvalidServiceType(exc.NodeCompositionPluginBadRequest): message = _("The NFP Node driver only supports the services " "VPN, Firewall and LB in a Service Chain") @@ -227,6 +229,8 @@ class NFPNodeDriver(driver_base.NodeDriverBase): def __init__(self): super(NFPNodeDriver, self).__init__() self._lbaas_plugin = None + self.nodes_count = None + self.thread_list = [] @property def name(self): @@ -329,6 +333,10 @@ def validate_update(self, context): service_type=context.current_profile['service_type'], vendor=context.current_profile['vendor']) + def _create_per_node_perf(self, context, network_function_id): + self._wait_for_network_function_operation_completion( + context, network_function_id, operation='create') + def create(self, context): context._plugin_context = self._get_resource_owner_context( context._plugin_context) @@ -336,8 +344,13 @@ def create(self, context): self._set_node_instance_network_function_map( context.plugin_session, context.current_node['id'], context.instance['id'], network_function_id) - self._wait_for_network_function_operation_completion( - context, network_function_id, operation='create') + th = thread_pool.dispatch(self._create_per_node_perf, context, network_function_id) + self.thread_list.append(th) + self.nodes_count -= 1 + + if not self.nodes_count: + for th in self.thread_list: + th.wait() def update(self, context): context._plugin_context = self._get_resource_owner_context( @@ -591,23 +604,39 @@ def _get_service_targets(self, context): {'service_type': service_type}) raise Exception("Service Targets are not created for the Node") - service_target_info = {'provider_ports': [], 'provider_pts': [], - 'consumer_ports': [], 'consumer_pts': []} + service_target_info = {'provider_ports': [], 'provider_subnet': None, 'provider_pts': [], 'provider_pt_objs': [], 'provider_ptg': [], + 'consumer_ports': [], 'consumer_subnet': None, 'consumer_pts': [], 'consumer_pt_objs': [], 'consumer_ptg': []} for service_target in provider_service_targets: policy_target = context.gbp_plugin.get_policy_target( context.plugin_context, service_target.policy_target_id) + policy_target_group = context.gbp_plugin.get_policy_target_group( + context.plugin_context, policy_target['policy_target_group_id']) port = context.core_plugin.get_port( context.plugin_context, policy_target['port_id']) + port['ip_address'] = port['fixed_ips'][0]['ip_address'] + subnet = context.core_plugin.get_subnet( + context.plugin_context, port['fixed_ips'][0]['subnet_id']) service_target_info['provider_ports'].append(port) + service_target_info['provider_subnet'] = subnet service_target_info['provider_pts'].append(policy_target['id']) + service_target_info['provider_pt_objs'].append(policy_target) + service_target_info['provider_ptg'].append(policy_target_group) for service_target in consumer_service_targets: policy_target = context.gbp_plugin.get_policy_target( context.plugin_context, service_target.policy_target_id) + policy_target_group = context.gbp_plugin.get_policy_target_group( + context.plugin_context, policy_target['policy_target_group_id']) port = context.core_plugin.get_port( context.plugin_context, policy_target['port_id']) + port['ip_address'] = port['fixed_ips'][0]['ip_address'] + subnet = context.core_plugin.get_subnet( + context.plugin_context, port['fixed_ips'][0]['subnet_id']) service_target_info['consumer_ports'].append(port) + service_target_info['consumer_subnet'] = subnet service_target_info['consumer_pts'].append(policy_target['id']) + service_target_info['consumer_pt_objs'].append(policy_target) + service_target_info['consumer_ptg'].append(policy_target_group) return service_target_info @@ -619,6 +648,8 @@ def _is_node_order_in_spec_supported(self, context): for spec in current_specs: node_list.extend(spec['nodes']) + #[AKASH] + self.nodes_count = len(node_list) for node_id in node_list: node_info = context.sc_plugin.get_servicechain_node( context.plugin_context, node_id) @@ -642,6 +673,21 @@ def _is_node_order_in_spec_supported(self, context): node_order=allowed_chain_combinations) def _create_network_function(self, context): + ''' + {'resource_owner_context': <>, + 'service_chain_instance': <>, + 'service_chain_node': <>, + 'service_profile': <>, + 'service_config': context.current_node.get('config'), + 'provider': {'pt':<>, 'ptg':<>, 'port':<>, 'subnet':<>}, + 'consumer': {'pt':<>, 'ptg':<>, 'port':<>, 'subnet':<>}, + 'management': {'pt':<>, 'ptg':<>, 'port':<>, 'subnet':<>}, + 'management_ptg_id': <>, + 'network_function_mode': nfp_constants.GBP_MODE, + } + ''' + nfp_create_nf_data = {} + sc_instance = context.instance service_targets = self._get_service_targets(context) if context.current_profile['service_type'] == pconst.LOADBALANCER: @@ -661,6 +707,51 @@ def _create_network_function(self, context): context.core_plugin.update_port( context.plugin_context, provider_port['id'], port) + provider = { + 'pt': service_targets.get('provider_pt_objs', [None])[0], + 'ptg': service_targets.get('provider_ptg', [None])[0], + 'port': service_targets.get('provider_ports', [None])[0], + 'subnet': service_targets.get('provider_subnet', None), + 'port_model': nfp_constants.GBP_PORT, + 'port_classification': nfp_constants.PROVIDER} + + consumer_pt = None + consumer_ptg = None + consumer_ports = None + if service_targets['consumer_pt_objs']: + consumer_pt = service_targets.get('consumer_pt_objs', [None])[0] + if service_targets['consumer_ptg']: + consumer_ptg = service_targets.get('consumer_ptg', [None])[0] + if service_targets['consumer_ports']: + consumer_ports = service_targets.get('consumer_ports', [None])[0] + consumer = { + 'pt': consumer_pt, + 'ptg': consumer_ptg, + 'port': consumer_ports, + 'subnet': service_targets.get('consumer_subnet', None), + 'port_model': nfp_constants.GBP_PORT, + 'port_classification': nfp_constants.CONSUMER} + + management = { + 'pt': None, + 'ptg': None, + 'port': None, + 'subnet': None, + 'port_model': nfp_constants.GBP_NETWORK, + 'port_classification': nfp_constants.MANAGEMENT} + + nfp_create_nf_data = { + 'resource_owner_context': context._plugin_context.to_dict(), + 'service_chain_instance': sc_instance, + 'service_chain_node': context.current_node, + 'service_profile': context.current_profile, + 'service_config': context.current_node.get('config'), + 'provider': provider, + 'consumer': consumer, + 'management': management, + 'management_ptg_id': sc_instance['management_ptg_id'], + 'network_function_mode': nfp_constants.GBP_MODE} + ''' port_info = [] if service_targets.get('provider_pts'): # Device case, for Base mode ports won't be available. @@ -687,9 +778,9 @@ def _create_network_function(self, context): 'port_info': port_info, 'network_function_mode': nfp_constants.GBP_MODE, } - + ''' return self.nfp_notifier.create_network_function( - context.plugin_context, network_function=network_function)['id'] + context.plugin_context, network_function=nfp_create_nf_data)['id'] def _set_node_instance_network_function_map( self, session, sc_node_id, sc_instance_id, network_function_id): diff --git a/gbpservice/nfp/bin/nfp_orch_agent.ini b/gbpservice/nfp/bin/nfp_orch_agent.ini index 2d20594cba..9ddfbccb0b 100644 --- a/gbpservice/nfp/bin/nfp_orch_agent.ini +++ b/gbpservice/nfp/bin/nfp_orch_agent.ini @@ -1,5 +1,5 @@ [DEFAULT] -workers=1 +workers=2 debug=False kombu_reconnect_delay=1.0 rabbit_use_ssl=False diff --git a/gbpservice/nfp/bin/nfp_proxy_agent.ini b/gbpservice/nfp/bin/nfp_proxy_agent.ini index 62792a47ab..8698c2a0fa 100644 --- a/gbpservice/nfp/bin/nfp_proxy_agent.ini +++ b/gbpservice/nfp/bin/nfp_proxy_agent.ini @@ -6,4 +6,4 @@ rabbit_use_ssl=False rabbit_virtual_host=/ modules_dir=gbpservice.nfp.proxy_agent.modules backend=unix_rest -periodic_interval=10 +periodic_interval=2 diff --git a/gbpservice/nfp/bin/proxy.ini b/gbpservice/nfp/bin/proxy.ini index 564cc9dda0..18babe5eea 100644 --- a/gbpservice/nfp/bin/proxy.ini +++ b/gbpservice/nfp/bin/proxy.ini @@ -5,7 +5,8 @@ max_connections=10 rest_server_address= 11.0.0.3 ##for docker ## rest_server_port= 8070 -worker_threads=40 +#[Note: worker threads should not be less than connect_max_wait_timeout/{periodic_interval or spacing for pull_notification}] +worker_threads=100 connect_max_wait_timeout=120 idle_max_wait_timeout=120 idle_min_wait_timeout=0.1 diff --git a/gbpservice/nfp/config_orchestrator/agent/otc_service_events.py b/gbpservice/nfp/config_orchestrator/agent/otc_service_events.py index 21b6f060e3..10b7693867 100644 --- a/gbpservice/nfp/config_orchestrator/agent/otc_service_events.py +++ b/gbpservice/nfp/config_orchestrator/agent/otc_service_events.py @@ -67,7 +67,7 @@ def _delete_service(self, context, resource): "DELETE", network_function_event=True) - @core_pt.poll_event_desc(event='SERVICE_CREATE_PENDING', spacing=5) + @core_pt.poll_event_desc(event='SERVICE_CREATE_PENDING', spacing=2) def create_sevice_pending_event(self, ev): event_data = ev.data ctxt = n_context.Context.from_dict(event_data['context']) diff --git a/gbpservice/nfp/core/context.py b/gbpservice/nfp/core/context.py index 8dc3337ad0..e002ca322b 100644 --- a/gbpservice/nfp/core/context.py +++ b/gbpservice/nfp/core/context.py @@ -15,20 +15,14 @@ nfp_context_store = threading.local() class NfpContext(object): - def __init__(self, **kwargs): - self.admin_token = kwargs.get('admin_token', None) - self.tenant_tokens = kwargs.get('tenant_tokens', None) - self.nfp_device_data = kwargs.get('nfp_device_data', None) - self.nfp_service_data = kwargs.get('nfp_service_data', None) - - def to_dict(self): - return {'admin_token': self.admin_token, - 'tenant_tokens': self.tenant_tokens, - 'nfp_device_data': self.nfp_device_data, - 'nfp_service_data': self.nfp_service_data} + def __init__(self, context): + self.context = context -def store_nfp_context(**kwargs): - nfp_context_store.context = NfpContext(**kwargs) + def get_context(self): + return self.context + +def store_nfp_context(context): + nfp_context_store.context = NfpContext(context) def clear_nfp_context(): nfp_context_store.context = None @@ -36,5 +30,5 @@ def clear_nfp_context(): def get_nfp_context(): context = getattr(nfp_context_store, 'context', None) if context: - return context.to_dict() + return context.get_context() return {} diff --git a/gbpservice/nfp/lib/RestClientOverUnix.py b/gbpservice/nfp/lib/RestClientOverUnix.py index adf0059e91..9f526975cf 100644 --- a/gbpservice/nfp/lib/RestClientOverUnix.py +++ b/gbpservice/nfp/lib/RestClientOverUnix.py @@ -82,7 +82,8 @@ def send_request(self, path, method_type, request_method='http', if method_type.upper() != 'GET': body = jsonutils.dumps(body) body = zlib.compress(body) - + if body: + LOG.error("Compressed data for method %s : %s" %(method_type, len(body))) path = '/v1/nfp/' + path url = urlparse.urlunsplit(( request_method, diff --git a/gbpservice/nfp/lib/transport.py b/gbpservice/nfp/lib/transport.py index 575aa1a5de..373bd4f2e9 100644 --- a/gbpservice/nfp/lib/transport.py +++ b/gbpservice/nfp/lib/transport.py @@ -203,6 +203,7 @@ def send_request_to_configurator(conf, context, body, elif conf.backend == UNIX_REST: try: + LOG.info("#############sends post_notification##############") resp, content = unix_rc.post(method_name, body=body) LOG.info( @@ -257,6 +258,7 @@ def get_response_from_configurator(conf): elif conf.backend == UNIX_REST: try: + LOG.info("#############sends get_notification##############") resp, content = unix_rc.get('get_notifications') content = jsonutils.loads(content) if content: diff --git a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py index a2861815d6..38e66ce850 100644 --- a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py +++ b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py @@ -65,3 +65,9 @@ def set_promiscuos_mode(self, token, port_id): self.network_handler = openstack_driver.NeutronClient(self.config) super(NFPGBPNetworkDriver, self).set_promiscuos_mode(token, port_id) self.network_handler = openstack_driver.GBPClient(self.config) + + def set_promiscuos_mode_perf(self, token, port_id): + # port_id = self.get_port_id(token, port_id) + self.network_handler = openstack_driver.NeutronClient(self.config) + super(NFPGBPNetworkDriver, self).set_promiscuos_mode(token, port_id) + self.network_handler = openstack_driver.GBPClient(self.config) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index 19cfc7bd43..f5450c9162 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -45,6 +45,7 @@ from gbpservice.nfp.core import context as nfp_core_context +from gbpservice.nfp.core import threadpool as core_tp HEAT_DRIVER_OPTS = [ cfg.StrOpt('svc_management_ptg_name', default='svc_management_ptg', @@ -484,7 +485,9 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) consumer = service_details['consumer_ptg'] provider = service_details['provider_ptg'] - _, consumer_eps = self._get_consumers_for_chain(auth_token, provider) + consumer_eps = service_details['consuming_external_policies'] + + #_, consumer_eps = self._get_consumers_for_chain(auth_token, provider) if (consumer is None) and (consumer_eps is None): return None @@ -688,7 +691,7 @@ def _get_site_conn_keys(self, template_resource_dict, keys.append(key) return keys - def _update_node_config_create(self, auth_token, tenant_id, service_chain_node, service_chain_instance, + def _create_node_config_data(self, auth_token, tenant_id, service_chain_node, service_chain_instance, provider, provider_port, consumer, consumer_port, network_function, mgmt_ip, service_details): @@ -808,11 +811,6 @@ def _update_node_config(self, auth_token, tenant_id, service_profile, provider, consumer_port, network_function, provider_port, update=False, mgmt_ip=None, consumer=None, service_details=None): - - if not update: - return self._update_node_config_create(auth_token, tenant_id, service_chain_node, service_chain_instance, - provider, provider_port, consumer, consumer_port, network_function, mgmt_ip, service_details) - nf_desc = None common_desc = {'network_function_id': network_function['id']} provider_cidr = provider_subnet = None @@ -1057,6 +1055,81 @@ def parse_template_config_string(self, config_str): tag_str = nfp_constants.HEAT_CONFIG_TAG return tag_str, service_config + def get_servicechain_node(self, gbp, admin_token, service_id, result): + servicechain_node = gbp.get_servicechain_node(admin_token, service_id) + result['result'] = servicechain_node + + def get_servicechain_instance(self, gbp, admin_token, service_chain_id, result): + servicechain_instance = gbp.get_servicechain_instance(admin_token, service_chain_id) + result['result'] = servicechain_instance + + def get_ptg(self, gbp, admin_token, pt_id, result): + policy_target = gbp.get_policy_target( + admin_token, pt_id) + policy_target_group = gbp.get_policy_target_group( + admin_token, + policy_target['policy_target_group_id']) + result['result'] = policy_target_group + + def get_provider_details(self, gbp, admin_token, pt_id, result): + l_result = {} + self.get_ptg(gbp, admin_token, pt_id, l_result) + ptg = l_result['result'] + result['ptg'] = ptg + _,consuming_eps = self._get_consumers_for_chain(admin_token, ptg) + result['consuming_eps'] = consuming_eps + + def get_provider_consumer_details(self, gbp, admin_token, nfp_context, thread_pool, result): + nfp_device_data = nfp_context['nfp_device_data'] + consumer_th = None + consumer_result = {} + consumer_port = None + consumer_subnet = None + for port_info in nfp_device_data.get('ports'): + port_classification = None + if port_info['port_model'] == nfp_constants.GBP_PORT: + policy_target_id = port_info['id'] + port_classification = port_info['port_classification'] + port_id = port_info['port_id'] + else: + port_id = port_info['id'] + + if port_classification == nfp_constants.CONSUMER: + consumer_port = port_info['neutron_info']['port'] + consumer_subnet = port_info['neutron_info']['subnet'] + + # consumer_result = {} + consumer_th = thread_pool.dispatch(self.get_ptg, self.gbp_client, admin_token, policy_target_id, consumer_result) + + elif port_classification == nfp_constants.PROVIDER: + LOG.info(_LI("provider info: %s") % (port_id)) + provider_port = port_info['neutron_info']['port'] + provider_subnet = port_info['neutron_info']['subnet'] + provider_policy_target_group = None + + provider_result = {} + provider_th = thread_pool.dispatch(self.get_provider_details, self.gbp_client, admin_token, policy_target_id, provider_result) + + if consumer_th: + consumer_th.wait() + provider_th.wait() + + consumer_policy_target_group = consumer_result.get('result', None) + provider_policy_target_group = provider_result.get('ptg', None) + consuming_external_policies = provider_result.get('consuming_eps', None) + + result['consumer'] = {} + result['provider'] = {} + + result['consumer']['ptg'] = consumer_policy_target_group + result['consumer']['port'] = consumer_port + result['consumer']['subnet'] = consumer_subnet + + result['provider']['ptg'] = provider_policy_target_group + result['provider']['port'] = provider_port + result['provider']['subnet'] = provider_subnet + result['provider']['consuming_eps'] = consuming_external_policies + def get_service_details_from_cache(self, nfp_context, network_function_details): network_function = network_function_details['network_function'] network_function_instance = network_function_details.get('network_function_instance') @@ -1071,45 +1144,31 @@ def get_service_details_from_cache(self, nfp_context, network_function_details): admin_token = self.keystoneclient.get_admin_token() heat_stack_id = network_function['heat_stack_id'] service_id = network_function['service_id'] - servicechain_node = self.gbp_client.get_servicechain_node(admin_token, - service_id) service_chain_id = network_function['service_chain_id'] - servicechain_instance = self.gbp_client.get_servicechain_instance( - admin_token, - service_chain_id) - nfp_device_data = nfp_context['nfp_device_data'] - if network_function_instance: - # for port_info in network_function_instance.get('port_info'): - for port_info in nfp_device_data.get('ports'): - port_classification = None - if port_info['port_model'] == nfp_constants.GBP_PORT: - policy_target_id = port_info['id'] - port_classification = port_info['port_classification'] - port_id = port_info['port_id'] - else: - port_id = port_info['id'] + thread_pool = core_tp.ThreadPool() - if port_classification == nfp_constants.CONSUMER: - consumer_port = port_info['neutron_info']['port'] - consumer_subnet = port_info['neutron_info']['subnet'] - policy_target = self.gbp_client.get_policy_target( - admin_token, policy_target_id) - consumer_policy_target_group = {'id': policy_target['policy_target_group_id']} + prov_cons_result={} + th3 = thread_pool.dispatch(self.get_provider_consumer_details, self.gbp_client, admin_token, nfp_context, thread_pool, prov_cons_result) + sc_node_result={} + th1 = thread_pool.dispatch(self.get_servicechain_node, self.gbp_client, admin_token, service_id, sc_node_result) + sc_instance_result={} + th2 = thread_pool.dispatch(self.get_servicechain_instance, self.gbp_client, admin_token, service_chain_id, sc_instance_result) + + th1.wait() + th2.wait() + th3.wait() - elif port_classification == nfp_constants.PROVIDER: - LOG.info(_LI("provider info: %s") % (port_id)) - provider_port = port_info['neutron_info']['port'] - provider_subnet = port_info['neutron_info']['subnet'] - provider_policy_target_group = None - - policy_target = self.gbp_client.get_policy_target( - admin_token, policy_target_id) - provider_policy_target_group = self.gbp_client.get_policy_target_group( - admin_token, - policy_target['policy_target_group_id']) - + servicechain_node = sc_node_result.get('result', None) + servicechain_instance = sc_instance_result.get('result', None) + consumer_policy_target_group = prov_cons_result['consumer']['ptg'] + provider_policy_target_group = prov_cons_result['provider']['ptg'] + provider_port = prov_cons_result['provider']['port'] + provider_subnet = prov_cons_result['provider']['subnet'] + consumer_port = prov_cons_result['consumer']['port'] + consumer_subnet = prov_cons_result['consumer']['subnet'] + service_details['consuming_external_policies'] = prov_cons_result['provider']['consuming_eps'] return { 'service_profile': None, @@ -1123,17 +1182,12 @@ def get_service_details_from_cache(self, nfp_context, network_function_details): 'mgmt_ip': mgmt_ip, 'heat_stack_id': heat_stack_id, 'provider_ptg': provider_policy_target_group, - 'consumer_ptg': consumer_policy_target_group + 'consumer_ptg': consumer_policy_target_group, + 'consuming_external_policies': service_details['consuming_external_policies'] } def get_service_details(self, network_function_details): - #[<--PERF] - nfp_context = nfp_core_context.get_nfp_context() - if nfp_context: - return self.get_service_details_from_cache(nfp_context, network_function_details) - - db_handler = nfp_db.NFPDbBase() db_session = nfp_db_api.get_session() network_function = network_function_details['network_function'] @@ -1313,39 +1367,37 @@ def _wait_for_stack_operation_complete(self, heatclient, stack_id, action, 'stack_owner': stack.stack_owner}) return None - def is_config_complete(self, stack_id, tenant_id, - network_function_details, heatclient=None): + def is_config_complete(self, nfp_context): - #[<--PERF] - nfp_context = nfp_core_context.get_nfp_context() - #[-->PERF] + token = nfp_context['resource_owner_context']['auth_token'] + tenant_id = nfp_context['resource_owner_context']['tenant_id'] + stack_id = nfp_context['heat_stack_id'] success_status = "COMPLETED" failure_status = "ERROR" intermediate_status = "IN_PROGRESS" - if not heatclient: - auth_token, resource_owner_tenant_id =\ - self._get_resource_owner_context() - timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) - if timeout_seconds: - timeout_mins = timeout_mins + 1 - user, password, tenant, auth_url =\ - self.keystoneclient.get_keystone_creds() - try: - heatclient = HeatClient( - user, - resource_owner_tenant_id, - cfg.CONF.heat_driver.heat_uri, - password, - auth_token=auth_token, - timeout_mins=timeout_mins) - except Exception: - LOG.exception(_LE("Failed to create heatclient object")) - return None + ''' + auth_token, resource_owner_tenant_id =\ + self._get_resource_owner_context() + ''' + timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) + if timeout_seconds: + timeout_mins = timeout_mins + 1 + user, password, tenant, auth_url =\ + self.keystoneclient.get_keystone_creds() + try: + heatclient = HeatClient( + user, + tenant_id, + cfg.CONF.heat_driver.heat_uri, + password, + auth_token=token, + timeout_mins=timeout_mins) + except Exception: + LOG.exception(_LE("Failed to create heatclient object")) + return None - #heatclient = self._get_heat_client(resource_owner_tenant_id, - # tenant_id=tenant_id) if not heatclient: return failure_status try: @@ -1353,12 +1405,14 @@ def is_config_complete(self, stack_id, tenant_id, if stack.stack_status == 'DELETE_FAILED': return failure_status elif stack.stack_status == 'CREATE_COMPLETE': + ''' if nfp_context: service_type = nfp_context['nfp_service_data']['service_details']['service_type'] if service_type.lower() == pconst.LOADBALANCER.lower(): self.loadbalancer_post_stack_create(network_function_details) else: self.loadbalancer_post_stack_create(network_function_details) + ''' return success_status elif stack.stack_status == 'UPDATE_COMPLETE': return success_status @@ -1412,8 +1466,65 @@ def is_config_delete_complete(self, stack_id, tenant_id): {'stack': stack_id}) return failure_status - def apply_config(self, network_function_details): - service_details = self.get_service_details(network_function_details) + def get_heat_client_perf(self, owner_tenant, provider_tenant, result): + heatclient = self._get_heat_client(owner_tenant, tenant_id=provider_tenant, assign_admin=True) + result['result'] = heatclient + + def update_node_config_perf(self, auth_token, provider_tenant_id, service_profile, + service_chain_node, service_chain_instance, provider, + consumer_port, network_function, + provider_port, mgmt_ip, consumer, service_details, result): + stack_template, stack_params = self._update_node_config( + auth_token, provider_tenant_id, service_profile, + service_chain_node, service_chain_instance, provider, + consumer_port, network_function, + provider_port, mgmt_ip=mgmt_ip, consumer=consumer, service_details=service_details) + result['stack_template'] = stack_template + result['stack_params'] = stack_params + + + def get_service_details_from_nfp_context(self, nfp_context): + network_function = nfp_context['network_function'] + network_function_instance = nfp_context['network_function_instance'] + service_details = nfp_context['service_details'] + mgmt_ip = nfp_context['management']['port']['ip_address'] + token = nfp_context['resource_owner_context']['auth_token'] + heat_stack_id = network_function['heat_stack_id'] + service_id = network_function['service_id'] + service_chain_id = network_function['service_chain_id'] + servicechain_instance = nfp_context['service_chain_instance'] + servicechain_node = nfp_context['service_chain_node'] + + consumer_policy_target_group = nfp_context['consumer']['ptg'] + provider_policy_target_group = nfp_context['provider']['ptg'] + provider_port = nfp_context['provider']['port'] + provider_subnet = nfp_context['provider']['subnet'] + consumer_port = nfp_context['consumer']['port'] + consumer_subnet = nfp_context['consumer']['subnet'] + _,consuming_eps = self._get_consumers_for_chain(token, provider_policy_target_group) + service_details['consuming_external_policies'] = consuming_eps + + return { + 'service_profile': None, + 'service_details': service_details, + 'servicechain_node': servicechain_node, + 'servicechain_instance': servicechain_instance, + 'consumer_port': consumer_port, + 'consumer_subnet': consumer_subnet, + 'provider_port': provider_port, + 'provider_subnet': provider_subnet, + 'mgmt_ip': mgmt_ip, + 'heat_stack_id': heat_stack_id, + 'provider_ptg': provider_policy_target_group, + 'consumer_ptg': consumer_policy_target_group, + 'consuming_external_policies': service_details['consuming_external_policies'] + } + + + def apply_config(self, nfp_context): + service_details = self.get_service_details_from_nfp_context(nfp_context) + # service_details = self.get_service_details(network_function_details) + network_function = nfp_context['network_function'] service_profile = service_details['service_profile'] service_chain_node = service_details['servicechain_node'] service_chain_instance = service_details['servicechain_instance'] @@ -1423,19 +1534,39 @@ def apply_config(self, network_function_details): provider_port = service_details['provider_port'] mgmt_ip = service_details['mgmt_ip'] + ''' if service_profile: service_details = transport.parse_service_flavor_string( service_profile['service_flavor']) + ''' + token = nfp_context['resource_owner_context']['auth_token'] + tenant_id = nfp_context['resource_owner_context']['tenant_id'] - auth_token, resource_owner_tenant_id =\ - self._get_resource_owner_context() + timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) + if timeout_seconds: + timeout_mins = timeout_mins + 1 - provider_tenant_id = provider['tenant_id'] - heatclient = self._get_heat_client(resource_owner_tenant_id, - tenant_id=provider_tenant_id, assign_admin=True) + user, password, tenant, auth_url =\ + self.keystoneclient.get_keystone_creds() + heatclient = HeatClient( + user, + tenant_id, + cfg.CONF.heat_driver.heat_uri, + password, + auth_token=token, + timeout_mins=timeout_mins) + + stack_template, stack_params = self._create_node_config_data(token, tenant_id, + service_chain_node, service_chain_instance, + provider, provider_port, consumer, consumer_port, + network_function, mgmt_ip, service_details) + + if not stack_template and not stack_params: + return None if not heatclient: return None + stack_name = ("stack_" + service_chain_instance['name'] + service_chain_node['name'] + service_chain_instance['id'][:8] + @@ -1443,15 +1574,7 @@ def apply_config(self, network_function_details): time.strftime("%Y%m%d%H%M%S")) # Heat does not accept space in stack name stack_name = stack_name.replace(" ", "") - stack_template, stack_params = self._update_node_config( - auth_token, provider_tenant_id, service_profile, - service_chain_node, service_chain_instance, provider, - consumer_port, network_function_details['network_function'], - provider_port, mgmt_ip=mgmt_ip, consumer=consumer, service_details=service_details) - - if not stack_template and not stack_params: - return None - + try: stack = heatclient.create(stack_name, stack_template, stack_params) except Exception as err: diff --git a/gbpservice/nfp/orchestrator/db/nfp_db.py b/gbpservice/nfp/orchestrator/db/nfp_db.py index 775b2b87f0..1fe6bcaafe 100644 --- a/gbpservice/nfp/orchestrator/db/nfp_db.py +++ b/gbpservice/nfp/orchestrator/db/nfp_db.py @@ -202,7 +202,7 @@ def _set_mgmt_port_for_nfd(self, session, network_function_device_db, session.add(port_info_db) session.flush() nfd_db.mgmt_port_id = port_info_db['id'] - del network_function_device['mgmt_port_id'] + # del network_function_device['mgmt_port_id'] def _set_plugged_in_port_for_nfd_interface(self, session, nfd_interface_db, interface, is_update=False): @@ -324,7 +324,11 @@ def update_network_function_device(self, session, session, network_function_device_db, updated_network_function_device) + mgmt_port_id = updated_network_function_device.pop('mgmt_port_id', None) + if mgmt_port_id: + updated_network_function_device['mgmt_port_id'] = mgmt_port_id['id'] network_function_device_db.update(updated_network_function_device) + updated_network_function_device['mgmt_port_id'] = mgmt_port_id return self._make_network_function_device_dict( network_function_device_db) diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index 2a2be4fc64..e280b3b972 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -30,6 +30,8 @@ from gbpservice.nfp.core import context as nfp_core_context +from gbpservice.nfp.core import threadpool as core_tp + LOG = nfp_logging.getLogger(__name__) @@ -54,7 +56,7 @@ class OrchestrationDriver(object): Launches the VM with all the management and data ports and a new VM is launched for each Network Service Instance """ - def __init__(self, config, supports_device_sharing=True, + def __init__(self, config, supports_device_sharing=False, supports_hotplug=True, max_interfaces=5): self.service_vendor = 'general' self.supports_device_sharing = supports_device_sharing @@ -94,6 +96,8 @@ def _get_setup_mode(self, config): return {nfp_constants.NEUTRON_MODE: True} def _get_admin_tenant_id(self, token=None): + return self.identity_handler.get_admin_tenant_id(token) + ''' try: (dummy, dummy, @@ -108,7 +112,7 @@ def _get_admin_tenant_id(self, token=None): except Exception: LOG.error(_LE("Failed to get admin's tenant ID")) raise - + ''' def _get_token(self, device_data_token): try: @@ -148,22 +152,16 @@ def _decrement_stats_counter(self, metric, by=1): def _is_device_sharing_supported(self): return self.supports_device_sharing - def _create_management_interface(self, device_data, network_handler=None): - token = self._get_token(device_data.get('token')) - if not token: - return None - + def _create_management_interface(self, token, admin_tenant_id, device_data, network_handler): name = nfp_constants.MANAGEMENT_INTERFACE_NAME mgmt_interface = network_handler.create_port( token, - self._get_admin_tenant_id(token=token), + admin_tenant_id, device_data['management_network_info']['id'], name=name) return {'id': mgmt_interface['id'], - #[<--PERF] 'port_id': mgmt_interface['port_id'], - #[PERF-->] 'port_model': (nfp_constants.GBP_PORT if device_data['service_details'][ 'network_mode'] == @@ -233,12 +231,16 @@ def _create_advance_sharing_interfaces(self, device_data, port['id'])}) return port_infos - def _get_interfaces_for_device_create(self, device_data, - network_handler=None): - mgmt_interface = self._create_management_interface( - device_data, - network_handler=network_handler) - return [mgmt_interface] + def _get_interfaces_for_device_create(self, token, admin_tenant_id, network_handler, device_data): + try: + mgmt_interface = self._create_management_interface( + token, + admin_tenant_id, + device_data, + network_handler) + device_data['interfaces'] = [mgmt_interface] + except Exception as e: + LOG.error("Creating interfaces for device create failed !") def _delete_interfaces(self, device_data, interfaces, network_handler=None): @@ -281,6 +283,24 @@ def _get_vendor_data(self, device_data, image_name): return None return vendor_data + def _get_vendor_data_perf(self, token, admin_tenant_id, image_name, device_data): + try: + metadata = self.compute_handler_nova.get_image_metadata( + token, + admin_tenant_id, + image_name) + except Exception as e: + self._increment_stats_counter('image_details_get_failures') + LOG.error(_LE('Failed to get image metadata for image ' + 'name: %(image_name)s. Error: %(error)s'), + {'image_name': image_name, 'error': e}) + return None + vendor_data = self._verify_vendor_data(image_name, metadata) + if not vendor_data: + return None + return vendor_data + + def _update_self_with_vendor_data(self, vendor_data, attr): attr_value = getattr(self, attr) if attr in vendor_data: @@ -312,6 +332,27 @@ def _update_vendor_data(self, device_data, token=None): " proceeding with default values") % (image_name)) + + def _update_vendor_data_perf(self, token, admin_tenant_id, image_name, device_data): + try: + vendor_data = self._get_vendor_data_perf(token, admin_tenant_id, image_name, device_data) + LOG.info(_LI("Vendor data, specified in image: %(vendor_data)s"), + {'vendor_data': vendor_data}) + if vendor_data: + self._update_self_with_vendor_data(vendor_data, + nfp_constants.MAXIMUM_INTERFACES) + self._update_self_with_vendor_data(vendor_data, + nfp_constants.SUPPORTS_SHARING) + self._update_self_with_vendor_data(vendor_data, + nfp_constants.SUPPORTS_HOTPLUG) + else: + LOG.info(_LI("No vendor data specified in image, " + "proceeding with default values")) + except Exception: + LOG.error(_LE("Error while getting metadata for image name: %s," + " proceeding with default values") + % (image_name)) + def _get_image_name(self, device_data): if device_data['service_details'].get('image_name'): image_name = device_data['service_details']['image_name'] @@ -322,6 +363,7 @@ def _get_image_name(self, device_data): % (device_data['service_details']['service_vendor'])) image_name = device_data['service_details']['service_vendor'] image_name = '%s' % image_name.lower() + device_data['service_details']['image_name'] = image_name return image_name def get_network_function_device_sharing_info(self, device_data): @@ -428,6 +470,44 @@ def select_network_function_device(self, devices, device_data): return device return None + def get_image_id(self, nova, token, admin_tenant_id, image_name, result): + try: + image_id = nova.get_image_id(token, admin_tenant_id, image_name) + result['image_id'] = image_id + except Exception as e: + LOG.error("Get image id failed !!") + + + def create_instance(self, nova, token, admin_tenant_id, image_id, flavor, interfaces_to_attach, instance_name, result): + try: + instance_id = nova.create_instance(token, admin_tenant_id, image_id, flavor, interfaces_to_attach, instance_name) + result['result'] = instance_id + except Exception as e: + LOG.error("Create instance failed !!!") + + def get_neutron_port_details(self, network_handler, token, port_id, result): + try: + (mgmt_ip_address, + mgmt_mac, mgmt_cidr, gateway_ip, + mgmt_port, mgmt_subnet) = network_handler.get_neutron_port_details(token, port_id) + + result['result'] = {'neutron_port': mgmt_port['port'], + 'neutron_subnet': mgmt_subnet['subnet'], + 'ip_address': mgmt_ip_address, + 'mac': mgmt_mac, + 'cidr': mgmt_cidr, + 'gateway_ip': gateway_ip} + except Exception as e: + import sys + import traceback + exc_type, exc_value, exc_traceback = sys.exc_info() + print traceback.format_exception(exc_type, exc_value, + exc_traceback) + LOG.error(traceback.format_exception(exc_type, exc_value, + exc_traceback)) + LOG.error("Failed to get neutron port details !!!") + + @_set_network_handler def create_network_function_device(self, device_data, network_handler=None): @@ -476,42 +556,41 @@ def create_network_function_device(self, device_data, raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) + + thread_pool = core_tp.ThreadPool() image_name = self._get_image_name(device_data) - if image_name: - self._update_vendor_data(device_data, - device_data.get('token')) - try: - interfaces = self._get_interfaces_for_device_create( - device_data, - network_handler=network_handler - ) - except Exception as e: + + ''' + token = self._get_token(device_data.get('token')) + if not token: + return None + + admin_tenant_id = self._get_admin_tenant_id(token=token) + ''' + token = device_data['token'] + admin_tenant_id = device_data['admin_tenant_id'] + + th1= thread_pool.dispatch(self._update_vendor_data_perf, token, admin_tenant_id, image_name, device_data) + th2 = thread_pool.dispatch(self._get_interfaces_for_device_create, token, admin_tenant_id, network_handler, device_data) + image_id_result = {} + th3 = thread_pool.dispatch(self.get_image_id, self.compute_handler_nova, token, admin_tenant_id, image_name, image_id_result) + + th1.wait() + th2.wait() + th3.wait() + + interfaces = device_data.pop('interfaces', None) + if not interfaces: LOG.exception(_LE('Failed to get interfaces for device creation.' 'Error: %(error)s'), {'error', e}) return None else: + management_interface = interfaces[0] self._increment_stats_counter('management_interfaces', by=len(interfaces)) - token = self._get_token(device_data.get('token')) - if not token: - return None - - if device_data['service_details'].get('image_name'): - image_name = device_data['service_details']['image_name'] - else: - LOG.info(_LI("No image name provided in service profile's " - "service flavor field, image will be selected " - "based on service vendor's name : %s") - % (device_data['service_details']['service_vendor'])) - image_name = device_data['service_details']['service_vendor'] - image_name = '%s' % image_name.lower() - try: - image_id = self.compute_handler_nova.get_image_id( - token, - self._get_admin_tenant_id(token=token), - image_name) - except Exception as e: + image_id = image_id_result.get('image_id', None) + if not image_id: self._increment_stats_counter('image_details_get_failures') LOG.error(_LE('Failed to get image id for device creation.' ' image name: %(image_name)s. Error: %(error)s'), @@ -590,12 +669,21 @@ def create_network_function_device(self, device_data, return None instance_name = device_data['name'] - try: - instance_id = self.compute_handler_nova.create_instance( - token, self._get_admin_tenant_id(token=token), - image_id, flavor, - interfaces_to_attach, instance_name) - except Exception as e: + + instance_id_result = {} + th1 = thread_pool.dispatch(self.create_instance, self.compute_handler_nova, + token, admin_tenant_id, image_id, flavor, + interfaces_to_attach, instance_name, instance_id_result) + + port_details_result = {} + th2 = thread_pool.dispatch(self.get_neutron_port_details, network_handler, token, + management_interface['port_id'], port_details_result) + + th1.wait() + th2.wait() + + instance_id = instance_id_result.get('result', None) + if not instance_id: self._increment_stats_counter('instance_launch_failures') LOG.error(_LE('Failed to create %(device_type)s instance.' 'Error: %(error)s'), @@ -611,39 +699,16 @@ def create_network_function_device(self, device_data, self._increment_stats_counter('instances') mgmt_ip_address = None - mgmt_neutron_port_info = {} - try: - for interface in interfaces: - if interface['port_classification'] == ( - nfp_constants.MANAGEMENT): - #[<--PERF] - (mgmt_ip_address, - mgmt_mac, mgmt_cidr, gateway_ip, - mgmt_port, mgmt_subnet) = network_handler.get_neutron_port_details(token, interface['port_id']) - - mgmt_neutron_port_info = {'neutron_port': mgmt_port, - 'neutron_subnet': mgmt_subnet, - 'ip_address': mgmt_ip_address, - 'mac': mgmt_mac, - 'cidr': mgmt_cidr, - 'gateway_ip': gateway_ip} - ''' - (mgmt_ip_address, - dummy, dummy, - dummy) = network_handler.get_port_details( - -token, interface['id']) - ''' - #[-->PERF] - break - except Exception as e: + mgmt_neutron_port_info = port_details_result.get('result', None) + + if not mgmt_neutron_port_info: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get management port details. ' 'Error: %(error)s'), {'error': e}) try: self.compute_handler_nova.delete_instance( token, - self._get_admin_tenant_id( - token=token), + admin_tenant_id, instance_id) except Exception as e: self._increment_stats_counter('instance_delete_failures') @@ -659,6 +724,7 @@ def create_network_function_device(self, device_data, by=len(interfaces)) return None + mgmt_ip_address = mgmt_neutron_port_info['ip_address'] return {'id': instance_id, 'name': instance_name, 'mgmt_ip_address': mgmt_ip_address, @@ -783,14 +849,10 @@ def get_network_function_device_status(self, device_data, raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) - token = self._get_token(device_data.get('token')) - if not token: - return None - try: device = self.compute_handler_nova.get_instance( - token, - self._get_admin_tenant_id(token=token), + device_data['token'], + device_data['tenant_id'], device_data['id']) except Exception: if ignore_failure: @@ -802,6 +864,12 @@ def get_network_function_device_status(self, device_data, return device['status'] + def set_promiscuos_mode(self, network_handler, token, port_id): + network_handler.set_promiscuos_mode_perf(token, port_id) + + def attach_interface(self, nova, token, admin_tenant_id, instance_id, port_id): + nova.attach_interface(token, admin_tenant_id, instance_id, port_id) + @_set_network_handler def plug_network_function_device_interfaces(self, device_data, network_handler=None): @@ -846,9 +914,6 @@ def plug_network_function_device_interfaces(self, device_data, raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) - token = self._get_token(device_data.get('token')) - if not token: - return None #[<--PERF] #This is already done in "create_network_function_device method of this class. @@ -858,6 +923,8 @@ def plug_network_function_device_interfaces(self, device_data, self._update_vendor_data(device_data) ''' #[-->PERF] + token = device_data['token'] + tenant_id = device_data['tenant_id'] update_ifaces = [] try: @@ -892,6 +959,21 @@ def plug_network_function_device_interfaces(self, device_data, elif self.setup_mode.get(nfp_constants.NEUTRON_MODE): pass else: + thread_pool = core_tp.ThreadPool() + threads = [] + for port in device_data['ports']: + service_type = device_data['service_details']['service_type'].lower() + if service_type == nfp_constants.FIREWALL.lower(): + th = thread_pool.dispatch(self.set_promiscuos_mode, network_handler, token, port['id']) + threads.append(th) + port_id = port['id'] + th = thread_pool.dispatch(self.attach_interface, self.compute_handler_nova, token, tenant_id, device_data['id'], port_id) + threads.append(th) + + for th in threads: + th.wait() + + """ for port in device_data['ports']: if port['port_classification'] == nfp_constants.PROVIDER: if ( @@ -899,19 +981,22 @@ def plug_network_function_device_interfaces(self, device_data, 'service_type'].lower() in [nfp_constants.FIREWALL.lower()] ): - network_handler.set_promiscuos_mode(token, - port['id']) - port_id = network_handler.get_port_id(token, - port['id']) + #network_handler.set_promiscuos_mode(token, + # port['id']) + eventlet.spawn_n(self.set_promiscuos_mode, network_handler, token, port['id']) #[<--PERF] - # Saving the neutron port id for the gbp pt - port['port_id'] = port_id + # port_id = network_handler.get_port_id(token, + # port['id']) + port_id = port['port_id'] #[-->PERF] + eventlet.spawn_n(self.attach_interface, self.compute_handler_nova, token, admin_tenant_id, device_data['id'], port_id) + ''' self.compute_handler_nova.attach_interface( token, self._get_admin_tenant_id(token=token), device_data['id'], port_id) + ''' break for port in device_data['ports']: if port['port_classification'] == nfp_constants.CONSUMER: @@ -922,18 +1007,20 @@ def plug_network_function_device_interfaces(self, device_data, ): network_handler.set_promiscuos_mode(token, port['id']) - port_id = network_handler.get_port_id(token, - port['id']) + #[<--PERF] - # Saving the neutron port id for the gbp pt - port['port_id'] = port_id + # port_id = network_handler.get_port_id(token, + # port['id']) + port_id = port['port_id'] #[-->PERF] + self.compute_handler_nova.attach_interface( token, self._get_admin_tenant_id(token=token), device_data['id'], port_id) break + """ except Exception as e: self._increment_stats_counter('interface_plug_failures') LOG.error(_LE('Failed to plug interface(s) to the device.' @@ -1149,12 +1236,37 @@ def get_network_function_device_healthcheck_info(self, device_data): ] } + + def get_neutron_details(self, token, device_port, network_handler): + LOG.info("$$$$$$$$$$$$$$$$$ GET_NEUTRON_PORT_DETAILS $$$$$$$$$$$$$$$$") + try: + neutron_port_id = network_handler.get_port_id(token, device_port['id']) + device_port['port_id'] = neutron_port_id + (ip, mac, cidr, gateway_ip, + port, subnet) = ( + network_handler.get_neutron_port_details(token, device_port['port_id']) + ) + device_port['neutron_info'] = {'ip': ip, + 'mac': mac, + 'cidr': cidr, + 'gateway_ip': gateway_ip, + 'port': port['port'], + 'subnet': subnet['subnet']} + except Exception as e: + import sys + import traceback + exc_type, exc_value, exc_traceback = sys.exc_info() + print traceback.format_exception(exc_type, exc_value, + exc_traceback) + + #wait_obj.set() + @_set_network_handler def get_network_function_device_port_info(self, device_data, network_handler=None): LOG.error("########## DEVICE DATA: %s" %(str(device_data))) if ( type(device_data['ports']) is not list or - + any(key not in port for port in device_data['ports'] for key in ['id', @@ -1168,7 +1280,49 @@ def get_network_function_device_port_info(self, device_data, network_handler=Non return None new_device_ports = [] + threads = [] + thread_pool = core_tp.ThreadPool() + + consumer_device_port = None + provider_device_port = None + + for port in device_data['ports']: + port_classification = port['port_classification'] + if port_classification == nfp_constants.CONSUMER: + consumer_device_port = port + elif port_classification == nfp_constants.PROVIDER: + provider_device_port = port + + th1 = None + th2 = None + if consumer_device_port: + th1 = thread_pool.dispatch(self.get_neutron_details, token, consumer_device_port, network_handler) + if provider_device_port: + th2 = thread_pool.dispatch(self.get_neutron_details, token, provider_device_port, network_handler) + + LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, start") + if th1: + th1.wait() + if th2: + th2.wait() + LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, end") + + ''' for device_port in device_data['ports']: + th = thread_pool.dispatch(self.get_neutron_details, token, device_port, network_handler) + threads.append(th) + + LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, start") + for thread in threads: + thread.wait() + LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, end") + ''' + LOG.info("@@@@@@@ CHECK PORT_INFO for neutron_info: %s" %(device_data['ports'])) + + + """ + neutron_port_id = network_handler.get_port_id(token, device_port['id']) + device_port['port_id'] = neutron_port_id try: (ip, mac, cidr, gateway_ip, port, subnet) = ( @@ -1189,6 +1343,7 @@ def get_network_function_device_port_info(self, device_data, network_handler=Non return None device_data['ports'] = new_device_ports + """ @_set_network_handler def get_network_function_device_config_info(self, device_data, @@ -1219,6 +1374,7 @@ def get_network_function_device_config_info(self, device_data, :raises: exceptions.IncompleteData """ + ''' if ( any(key not in device_data for key in ['service_details', @@ -1242,7 +1398,7 @@ def get_network_function_device_config_info(self, device_data, ): raise exceptions.IncompleteData() - token = self._get_token(device_data.get('token')) + token = device if not token: return None @@ -1297,13 +1453,23 @@ def get_network_function_device_config_info(self, device_data, ' for get device config info operation')) raise e return None + ''' + mgmt_ip = device_data.get('mgmt_ip', None) + provider_ip = device_data.get('provider_ip', None) + provider_mac = device_data.get('provider_mac', None) + provider_cidr = device_data.get('provider_cidr', None) + provider_gateway_ip = device_data.get('provider_gateway_ip', None) + consumer_ip = device_data.get('consumer_ip', None) + consumer_mac = device_data.get('consumer_mac', None) + consumer_cidr = device_data.get('consumer_cidr', None) + consumer_gateway_ip = device_data.get('consumer_gateway_ip', None) return { 'config': [ { 'resource': nfp_constants.INTERFACE_RESOURCE, 'resource_data': { - 'mgmt_ip': device_data['mgmt_ip_address'], + 'mgmt_ip': mgmt_ip, 'provider_ip': provider_ip, 'provider_cidr': provider_cidr, 'provider_interface_index': 2, @@ -1318,7 +1484,7 @@ def get_network_function_device_config_info(self, device_data, { 'resource': nfp_constants.ROUTES_RESOURCE, 'resource_data': { - 'mgmt_ip': device_data['mgmt_ip_address'], + 'mgmt_ip': mgmt_ip, 'source_cidrs': ([provider_cidr, consumer_cidr] if consumer_cidr else [provider_cidr]), diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index d86c225c7e..b4dc0b4458 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -34,6 +34,7 @@ from gbpservice.nfp.core import log as nfp_logging from gbpservice.nfp.core import context as nfp_core_context + LOG = nfp_logging.getLogger(__name__) STOP_POLLING = {'poll': False} @@ -56,7 +57,7 @@ def events_init(controller, config, device_orchestrator): 'DEVICE_CONFIGURED', "DELETE_CONFIGURATION", 'DELETE_NETWORK_FUNCTION_DEVICE', 'DELETE_CONFIGURATION_COMPLETED', 'DEVICE_BEING_DELETED', - 'DEVICE_NOT_REACHABLE', 'DEVICE_CONFIGURATION_FAILED'] + 'DEVICE_NOT_REACHABLE', 'DEVICE_CONFIGURATION_FAILED', 'DEVICE_UP'] events_to_register = [] for event in events: events_to_register.append( @@ -120,14 +121,6 @@ def network_function_notification(self, context, notification_data): logging_context = request_info.get('logging_context') nfp_logging.store_logging_context(**logging_context) - #[<--PERF] - try: - nfp_context = request_info['nfp_context'] - nfp_context['admin_token'] = None - except KeyError: - request_info['nfp_context'] = None - #[-->PERF] - for response in responses: resource = response.get('resource') data = response.get('data') @@ -554,7 +547,48 @@ def _update_device_data(self, device, device_data): device.update(device_data) return device - # Create path + def _prepare_device_data_from_nfp_context(self, nfp_context): + device_data = {} + + network_function = nfp_context['network_function'] + network_function_instance = nfp_context['network_function_instance'] + service_details = nfp_context['service_details'] + + device_data['token'] = nfp_context['resource_owner_context']['auth_token'] + device_data['admin_tenant_id'] = nfp_context['resource_owner_context']['admin_tenant_id'] + device_data['name'] = network_function_instance['name'] + device_data['share_existing_device'] = nfp_context['share_existing_device'] + + management_network_info = { + 'id': nfp_context['management_ptg_id'], + 'port_model': nfp_constants.GBP_NETWORK + } + consumer = nfp_context['consumer'] + provider = nfp_context['provider'] + ports = [] + if consumer['port']: + ports.append({'id': consumer['port']['id'], + 'port_classification': consumer['port_classification'], + 'port_model': consumer['port_model']}) + if provider['port']: + ports.append({'id': provider['port']['id'], + 'port_classification': provider['port_classification'], + 'port_model': provider['port_model']}) + + device_data['management_network_info'] = management_network_info + + device_data['network_function_id'] = network_function['id'] + device_data['service_chain_id'] = network_function['service_chain_id'] + device_data['network_function_instance_id'] = network_function_instance['id'] + device_data['tenant_id'] = network_function_instance['tenant_id'] + device_data['ports'] = ports + device_data['service_details'] = service_details + device_data['service_details']['network_mode'] = nfp_constants.GBP_MODE + device_data['service_vendor'] = service_details['service_vendor'] + + return device_data + + # Create path def create_network_function_device(self, event): """ Returns device instance for a new service @@ -562,23 +596,23 @@ def create_network_function_device(self, event): new service or it creates new device instance """ - #[<--PERF] - # Since this is not internal event, read the context from event - # and store in the current thread. - nfp_context = event.data['nfp_context'] - nfp_core_context.store_nfp_context(**nfp_context) - #[PERF -->] - nfd_request = event.data + nfp_context = nfd_request + + + service_details = nfp_context['service_details'] device = None LOG.info(_LI("Device Orchestrator received create network service " "device request with data %(data)s"), {'data': nfd_request}) - device_data = self._get_device_data(nfd_request, is_create_request=True) + # device_data = self._get_device_data(nfd_request, is_create_request=True) + orchestration_driver = self._get_orchestration_driver( - device_data['service_details']['service_vendor']) + service_details['service_vendor']) + device_data = self._prepare_device_data_from_nfp_context(nfp_context) + dev_sharing_info = ( orchestration_driver.get_network_function_device_sharing_info( device_data)) @@ -600,6 +634,7 @@ def create_network_function_device(self, event): else: LOG.info(_LI("No Device exists for sharing, Creating new device," "device request: %(device)s"), {'device': nfd_request}) + LOG.info("Prepared device_data %s" %(device_data)) driver_device_info = ( orchestration_driver.create_network_function_device( device_data)) @@ -609,27 +644,24 @@ def create_network_function_device(self, event): event_data=nfd_request, is_internal_event=True) return None + + management = nfp_context['management'] + management['port'] = driver_device_info['mgmt_neutron_port_info']['neutron_port'] + management['port']['ip_address'] = management['port']['fixed_ips'][0]['ip_address'] + management['subnet'] = driver_device_info['mgmt_neutron_port_info']['neutron_subnet'] # Update newly created device with required params device = self._update_device_data(driver_device_info, device_data) device['network_function_device_id'] = device['id'] - #[<--PERF] - for port in device['ports']: - if port['port_classification'] == nfp_constants.MANAGEMENT: - port['neutron_info'] = driver_device_info['mgmt_neutron_port_info'] - break - #[-->PERF] - # Create DB entry with status as DEVICE_SPAWNING network_function_device = self._create_network_function_device_db(device, 'DEVICE_SPAWNING') - #[<--PERF] - device['network_function_device'] = network_function_device - nfp_context = nfp_core_context.get_nfp_context() - nfp_context['nfp_device_data'].update(device) - #[-->PERF] + LOG.info("@@@@@@@@@@ DEVICE - %s" %(str(device))) + #[PERF-TODO] Wrong by nfp_db method needs in this format + network_function_device['mgmt_port_id'] = device['mgmt_port_id'] + nfp_context['network_function_device'] = network_function_device # Create an event to NSO, to give device_id device_created_data = { @@ -637,6 +669,8 @@ def create_network_function_device(self, event): nfd_request['network_function_instance']['id']), 'network_function_device_id': device['id'], } + + self._create_event(event_id='DEVICE_SPAWNING', event_data=nfp_context, is_poll_event=True, @@ -647,14 +681,18 @@ def create_network_function_device(self, event): @poll_event_desc(event='DEVICE_SPAWNING', spacing=2) def check_device_is_up(self, event): - #[<--PERF] nfp_context = event.data - device = nfp_context['nfp_device_data'] - # device = event.data - #[-->PERF] - + service_details= nfp_context['service_details'] + network_function_device = nfp_context['network_function_device'] + token = nfp_context['resource_owner_context']['auth_token'] + tenant_id = nfp_context['resource_owner_context']['tenant_id'] + device = { + 'token': token, + 'tenant_id': tenant_id, + 'id': network_function_device['id'], + 'service_details': service_details} orchestration_driver = self._get_orchestration_driver( - device['service_details']['service_vendor']) + service_details['service_vendor']) is_device_up = ( orchestration_driver.get_network_function_device_status(device)) if is_device_up == nfp_constants.ACTIVE: @@ -666,17 +704,20 @@ def check_device_is_up(self, event): ''' #[<--PERF] - self._create_event(event_id='PLUG_INTERFACES', - event_data=nfp_context, - is_internal_event=True) - - LOG.error("$$$$$$$$ %s" %(str(device))) - orchestration_driver.get_network_function_device_port_info(device) + # LOG.info("@@@@@@ Profile: get_network_function_device_port_info, start @@@@") + # orchestration_driver.get_network_function_device_port_info(device) + # LOG.info("@@@@@@ Profile: get_network_function_device_port_info, end @@@@") # create event DEVICE_UP self._create_event(event_id='DEVICE_UP', + event_data=nfp_context) + + LOG.info("@@@@@@ Profile: plug_interfaces, start @@@@") + self._create_event(event_id='PLUG_INTERFACES', event_data=nfp_context, is_internal_event=True) + LOG.info("@@@@@@ Profile: plug_interfaces, end @@@@") + self._update_network_function_device_db(device, 'HEALTH_CHECK_PENDING') #[-->PERF] @@ -695,16 +736,31 @@ def check_device_is_up(self, event): return CONTINUE_POLLING def perform_health_check(self, event): + ''' #[<--PERF] nfp_context = event.data nfp_core_context.store_nfp_context(**nfp_context) # device = event.data device = nfp_context['nfp_device_data'] #[-->PERF] - + ''' + nfp_context = event.data + service_details = nfp_context['service_details'] + network_function_device = nfp_context['network_function_device'] + network_function = nfp_context['network_function'] + network_function_instance = nfp_context['network_function_instance'] + mgmt_ip_address = nfp_context['management']['port']['ip_address'] # The driver tells which protocol / port to monitor ?? orchestration_driver = self._get_orchestration_driver( - device['service_details']['service_vendor']) + service_details['service_vendor']) + device ={ + 'id': network_function_device['id'], + 'mgmt_ip_address': mgmt_ip_address, + 'service_details': service_details, + 'network_function_id': network_function['id'], + 'network_function_instance_id': network_function_instance['id'], + 'nfp_context': nfp_context + } hm_req = ( orchestration_driver.get_network_function_device_healthcheck_info( device)) @@ -778,8 +834,8 @@ def _prepare_device_data(self, device_info): #[<--PERF] def device_healthy(self, event): - nfp_context = event.data['nfp_context'] - device = nfp_context['nfp_device_data'] + nfp_context = event.data.get('nfp_context', None) + device = nfp_context['network_function_device'] self._update_network_function_device_db(device, 'HEALTH_CHECK_COMPLETED') self._create_event(event_id='DEVICE_ACTIVE', event_data=nfp_context) self._create_event(event_id='CONFIGURE_DEVICE', @@ -793,9 +849,31 @@ def plug_interfaces(self, event, is_event_call=True): # so, we should not generate CONFIGURE_DEVICE & should not update # DB with HEALTH_CHECK_COMPLETED. nfp_context = event.data - device = nfp_context['nfp_device_data'] + service_details = nfp_context['service_details'] + network_function_device = nfp_context['network_function_device'] + token = nfp_context['resource_owner_context']['auth_token'] + tenant_id = nfp_context['resource_owner_context']['tenant_id'] + # device = nfp_context['nfp_device_data'] orchestration_driver = self._get_orchestration_driver( - device['service_details']['service_vendor']) + service_details['service_vendor']) + consumer = nfp_context['consumer'] + provider = nfp_context['provider'] + ports = [] + if consumer['port']: + ports.append({'id': consumer['port']['id'], + 'port_classification': consumer['port_classification'], + 'port_model': consumer['port_model']}) + if provider['port']: + ports.append({'id': provider['port']['id'], + 'port_classification': provider['port_classification'], + 'port_model': provider['port_model']}) + device = { + 'id': network_function_device['id'], + 'ports': ports, + 'service_details': service_details, + 'token': token, + 'tenant_id': tenant_id, + 'interfaces_in_use': network_function_device['interfaces_in_use']} _ifaces_plugged_in, advance_sharing_ifaces = ( orchestration_driver.plug_network_function_device_interfaces( @@ -806,6 +884,7 @@ def plug_interfaces(self, event, is_event_call=True): device, advance_sharing_ifaces) self._increment_device_interface_count(device) + #[PERF - TODO] - Check how incremented ref count can be updated in DB ''' if is_event_call: @@ -839,18 +918,51 @@ def plug_interfaces(self, event, is_event_call=True): ''' def create_device_configuration(self, event): + ''' #[<--PERF] nfp_context = event.data nfp_core_context.store_nfp_context(**nfp_context) # device = event.data device = nfp_context['nfp_device_data'] #[-->PERF] + ''' + nfp_context = event.data + service_details = nfp_context['service_details'] + token = nfp_context['resource_owner_context']['auth_token'] + tenant_id = nfp_context['resource_owner_context']['tenant_id'] + consumer = nfp_context['consumer'] + provider = nfp_context['provider'] + management = nfp_context['management'] + network_function = nfp_context['network_function'] + network_function_instance = nfp_context['network_function_instance'] + network_function_device = nfp_context['network_function_device'] orchestration_driver = self._get_orchestration_driver( - device['service_details']['service_vendor']) + service_details['service_vendor']) + device = { + 'mgmt_ip': management['port']['ip_address'], + 'provider_ip': provider['port']['ip_address'], + 'provider_cidr': provider['subnet']['cidr'], + 'provider_mac': provider['port']['mac_address'], + 'provider_gateway_ip': provider['subnet']['gateway_ip']} + + if consumer['port'] and consumer['subnet']: + device.update({'consumer_ip': consumer['port']['ip_address'], + 'consumer_cidr': consumer['subnet']['cidr'], + 'consumer_mac': consumer['port']['mac_address'], + 'consumer_gateway_ip': consumer['subnet']['gateway_ip']}) + config_params = ( orchestration_driver.get_network_function_device_config_info( device, is_create_request=True)) + device.update({ + 'id': network_function_device['id'], + 'mgmt_ip_address': management['port']['ip_address'], + 'service_details': service_details, + 'network_function_id': network_function['id'], + 'network_function_instance_id': network_function_instance['id'], + 'nfp_context': nfp_context}) + if not config_params: self._create_event(event_id='DRIVER_ERROR', event_data=device, @@ -861,13 +973,17 @@ def create_device_configuration(self, event): device, config_params) def device_configuration_complete(self, event): + ''' #[<--PERF] nfp_context = event.data['nfp_context'] # device_info = event.data # device = self._prepare_device_data(device_info) device = nfp_context['nfp_device_data'] #[-->PERF] - + ''' + nfp_context = event.data.get('nfp_context', None) + device = nfp_context['network_function_device'] + # Change status to active in DB and generate an event DEVICE_ACTIVE # to inform NSO self._increment_device_ref_count(device) @@ -1077,7 +1193,7 @@ def _get_request_info(self, device, operation): 'logging_context': nfp_logging.get_logging_context(), #[<--PERF] #Add so that notifications can work on cached data - 'nfp_context': nfp_core_context.get_nfp_context() + 'nfp_context': device.get('nfp_context', None) #[-->PERF] } nfd_ip = device['mgmt_ip_address'] diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 414a551b80..502689ec50 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -281,15 +281,6 @@ def network_function_notification(self, context, notification_data): nfp_logging.store_logging_context(**logging_context) serialize = False - #[<--PERF] - try: - nfp_context = request_info['nfp_context'] - nfp_context['admin_token'] = None - except KeyError: - request_info['nfp_context'] = None - #[-->PERF] - - for response in responses: resource = response.get('resource') data = response.get('data') @@ -620,16 +611,24 @@ def _report_logging_info(self, nf, nfi, service_type, def create_network_function(self, context, network_function_info): self._validate_create_service_input(context, network_function_info) + + admin_token = self.keystoneclient.get_admin_token() + admin_tenant_id = self.keystoneclient.get_admin_tenant_id(admin_token) + network_function_info['resource_owner_context']['auth_token'] = admin_token + network_function_info['resource_owner_context']['tenant_id'] = admin_tenant_id + network_function_info['resource_owner_context']['admin_tenant_id'] = admin_tenant_id + # GBP or Neutron mode = network_function_info['network_function_mode'] - service_profile_id = network_function_info['service_profile_id'] - service_id = network_function_info['service_id'] - admin_token = self.keystoneclient.get_admin_token() - service_profile = self.gbpclient.get_service_profile( - admin_token, service_profile_id) - service_chain_id = network_function_info.get('service_chain_id') + service_profile = network_function_info['service_profile'] + admin_token = network_function_info['resource_owner_context']['auth_token'] + tenant_id = network_function_info['resource_owner_context']['tenant_id'] + 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'] service_details = transport.parse_service_flavor_string( service_profile['service_flavor']) + base_mode_support = (True if service_details['device_type'] == 'None' else False) service_vendor = service_details['service_vendor'] @@ -640,7 +639,7 @@ def create_network_function(self, context, network_function_info): network_function = { 'name': name, 'description': '', - 'tenant_id': network_function_info['tenant_id'], + '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, @@ -671,6 +670,7 @@ def create_network_function(self, context, network_function_info): service_config_str) return network_function + ''' if mode == nfp_constants.GBP_MODE: management_network_info = { 'id': network_function_info['management_ptg_id'], @@ -678,9 +678,17 @@ def create_network_function(self, context, network_function_info): } else: management_network_info = {} + + port_info = [] + for ele in [consumer, provider]: + port_info.append({'id': ele['pt']['id'], + 'port_model': ele['port_model'], + 'port_classification': ele['port_classification'] + }) + create_network_function_instance_request = { 'network_function': network_function, - 'network_function_port_info': network_function_info['port_info'], + 'network_function_port_info': port_info, 'management_network_info': management_network_info, 'service_type': service_profile['service_type'], 'service_details': service_details, @@ -695,8 +703,15 @@ def create_network_function(self, context, network_function_info): # Save this context in thread - as "CREATE_NETWORK_FUNCTION_INSTANCE" is internal event" nfp_core_context.store_nfp_context(**nfp_context) ##[PERF-->] + ''' - + nfp_context = 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 + create_network_function_instance_request = nfp_context # Create and event to perform Network service instance self._create_event('CREATE_NETWORK_FUNCTION_INSTANCE', @@ -775,34 +790,42 @@ def delete_user_config(self, event): is_poll_event=True, original_event=event) def create_network_function_instance(self, event): - #[<--PERF] - #Get from the thread context - nfp_context = nfp_core_context.get_nfp_context() - request_data = nfp_context['nfp_service_data'] - # request_data = event.data - #[PERF-->] - - name = '%s_%s' % (request_data['network_function']['name'], - request_data['network_function']['id']) + nfp_context = event.data + + network_function = nfp_context['network_function'] + service_profile = nfp_context['service_profile'] + service_details = nfp_context['service_details'] + consumer = nfp_context['consumer'] + provider = nfp_context['provider'] + + port_info = [] + for ele in [consumer, provider]: + if ele['pt']: + port_info.append({'id': ele['pt']['id'], + 'port_model': ele['port_model'], + 'port_classification': ele['port_classification'] + }) + + name = '%s_%s' % (network_function['name'], + network_function['id']) create_nfi_request = { 'name': name, - 'tenant_id': request_data['network_function']['tenant_id'], + 'tenant_id': network_function['tenant_id'], 'status': nfp_constants.PENDING_CREATE, - 'network_function_id': request_data['network_function']['id'], - 'service_type': request_data['service_type'], - 'service_vendor': ( - request_data['service_details']['service_vendor']), - 'share_existing_device': request_data['share_existing_device'], - 'port_info': request_data['network_function_port_info'], + '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, } nfi_db = self.db_handler.create_network_function_instance( self.db_session, create_nfi_request) # Sending LogMeta Details to visibility - self._report_logging_info(request_data['network_function'], nfi_db, - request_data['service_type'], - request_data['service_details'][ - 'service_vendor']) + self._report_logging_info(network_function, nfi_db, + service_details['service_type'], + service_details['service_vendor']) + ''' request_data['service_details'].update( service_type=request_data['service_type']) create_nfd_request = { @@ -827,6 +850,10 @@ def create_network_function_instance(self, event): # Update the context in event. create_nfd_request['nfp_context'] = nfp_context #[PERF -->] + ''' + + nfp_context['network_function_instance'] = nfi_db + create_nfd_request = nfp_context LOG.info(_LI("[Event:CreateService]")) self._create_event('CREATE_NETWORK_FUNCTION_DEVICE', @@ -843,11 +870,21 @@ def handle_device_created(self, event): return def handle_device_active(self, event): + ''' #[<--PERF] nfp_context = event.data nfp_core_context.store_nfp_context(**nfp_context) request_data = nfp_context['nfp_device_data'] # request_data = event.data + ''' + nfp_context = event.data + network_function_instance = nfp_context['network_function_instance'] + network_function_device = nfp_context['network_function_device'] + network_function = nfp_context['network_function'] + + request_data = {'network_function_device_id': network_function_device['id'], + 'network_function_instance_id': network_function_instance['id']} + nfi = { 'status': nfp_constants.ACTIVE, 'network_function_device_id': request_data[ @@ -855,15 +892,22 @@ def handle_device_active(self, event): } nfi = self.db_handler.update_network_function_instance( self.db_session, request_data['network_function_instance_id'], nfi) + network_function_instance['status'] = nfp_constants.ACTIVE + network_function_instance['network_function_device_id'] = network_function_device['id'] + ''' network_function = self.db_handler.get_network_function( self.db_session, nfi['network_function_id']) ''' + ''' nfp_context['nfp_service_data']['network_function_instance']['status'] = nfp_constants.ACTIVE nfp_context['nfp_service_data']['network_function_instance']['network_function_device_id'] = request_data[ 'network_function_device_id'] + network_function = nfp_context['nfp_service_data']['network_function'] + ''' service_config = network_function['service_config'] + nfp_core_context.store_nfp_context(nfp_context) self.create_network_function_user_config(network_function['id'], service_config) @@ -871,32 +915,28 @@ def handle_device_active(self, event): def apply_user_config(self, event): #[<--PERF] nfp_context = event.data['nfp_context'] - nfp_core_context.store_nfp_context(**nfp_context) + nfp_core_context.store_nfp_context(nfp_context) #[-->PERF] - + network_function = nfp_context['network_function'] request_data = event.data network_function_details = self.get_network_function_details( - request_data['network_function_id']) + network_function['id']) request_data['heat_stack_id'], heat_client = self.config_driver.apply_config( - network_function_details) # Heat driver to launch stack - network_function = network_function_details['network_function'] + nfp_context) # Heat driver to launch stack request_data['network_function_id'] = network_function['id'] if not request_data['heat_stack_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 heat_stack_id: %s" % (request_data['heat_stack_id'])) #[<--PERF] - request_data['nfp_context'] = nfp_context - # request_data['heat_client'] = heat_client - nfp_context['nfp_service_data']['network_function'].update({'heat_stack_id': request_data['heat_stack_id'], + nfp_context['heat_stack_id'] = request_data['heat_stack_id'] + nfp_context['network_function'].update({'heat_stack_id': request_data['heat_stack_id'], 'description': network_function['description']}) self._create_event('APPLY_USER_CONFIG_IN_PROGRESS', - event_data=request_data, + event_data=nfp_context, is_poll_event=True, original_event=event) self.db_handler.update_network_function( @@ -1045,8 +1085,10 @@ def delete_network_function_instance(self, event): # FIXME: Add all possible validations here def _validate_create_service_input(self, context, create_service_request): - required_attributes = ["tenant_id", "service_id", "service_chain_id", - "service_profile_id", "network_function_mode"] + 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) - @@ -1055,8 +1097,7 @@ def _validate_create_service_input(self, context, create_service_request): required_data=", ".join(missing_keys), request="Create Network Function") if create_service_request['network_function_mode'].lower() == "gbp": - gbp_required_attributes = ["port_info", "service_chain_id", - "management_ptg_id"] + gbp_required_attributes = ["management_ptg_id"] if (set(gbp_required_attributes) & set(create_service_request.keys()) != set(gbp_required_attributes)): @@ -1067,26 +1108,19 @@ def _validate_create_service_input(self, context, create_service_request): request="Create Network Function") def check_for_user_config_complete(self, event): - request_data = event.data - - #[<--PERF] - nfp_context = request_data['nfp_context'] - nfp_core_context.store_nfp_context(**nfp_context) - #[-->PERF] - - config_status = self.config_driver.is_config_complete( - request_data['heat_stack_id'], request_data['tenant_id'], - request_data['network_function_details']) + nfp_context = event.data + network_function = nfp_context['network_function'] + config_status = self.config_driver.is_config_complete(nfp_context) if config_status == nfp_constants.ERROR: LOG.info(_LI("NSO: applying user config failed for " "network function %(network_function_id)s data " - "%(data)s"), {'data': request_data, + "%(data)s"), {'data': nfp_context, 'network_function_id': - request_data['network_function_id']}) + network_function['id']}) updated_network_function = {'status': nfp_constants.ERROR} self.db_handler.update_network_function( self.db_session, - request_data['network_function_id'], + network_function['id'], updated_network_function) self._controller.event_done(event) return STOP_POLLING @@ -1096,10 +1130,10 @@ def check_for_user_config_complete(self, event): LOG.info(_LI("NSO: applying user config is successfull moving " "network function %(network_function_id)s to ACTIVE"), {'network_function_id': - request_data['network_function_id']}) + network_function['id']}) self.db_handler.update_network_function( self.db_session, - request_data['network_function_id'], + network_function['id'], updated_network_function) self._controller.event_done(event) return STOP_POLLING @@ -1555,12 +1589,11 @@ def get_network_function_details(self, network_function_id): service_type = None nfp_context = nfp_core_context.get_nfp_context() - if nfp_context !={} and nfp_context['nfp_service_data']: - network_function = nfp_context['nfp_service_data']['network_function'] - network_function_instance = nfp_context['nfp_service_data']['network_function_instance'] - if nfp_context['nfp_device_data']: - network_function_device = nfp_context['nfp_device_data']['network_function_device'] - service_type = nfp_context['nfp_service_data']['service_details']['service_type'] + if nfp_context: + network_function = nfp_context['network_function'] + network_function_instance = nfp_context['network_function_instance'] + network_function_device = nfp_context['network_function_device'] + service_type = nfp_context['service_details']['service_type'] if not network_function: network_function = self.db_handler.get_network_function( diff --git a/gbpservice/nfp/orchestrator/openstack/openstack_driver.py b/gbpservice/nfp/orchestrator/openstack/openstack_driver.py index 869983c1b4..24a3091297 100644 --- a/gbpservice/nfp/orchestrator/openstack/openstack_driver.py +++ b/gbpservice/nfp/orchestrator/openstack/openstack_driver.py @@ -41,6 +41,7 @@ def __init__(self, config, username=None, self.tenant_name = (tenant_name or config.keystone_authtoken.admin_tenant_name) self.token = None + self.admin_tenant_id = None class KeystoneClient(OpenstackApi): @@ -103,6 +104,13 @@ def get_scoped_keystone_token(self, user, password, tenant_name, else: return scoped_token + def get_admin_tenant_id(self, token): + if not self.admin_tenant_id: + _,_,name,_ = self.get_keystone_creds() + self.admin_tenant_id = self.get_tenant_id(token, name) + + return self.admin_tenant_id + def get_tenant_id(self, token, tenant_name): """ Get the tenant UUID associated to tenant name diff --git a/gbpservice/nfp/proxy_agent/proxy/proxy.py b/gbpservice/nfp/proxy_agent/proxy/proxy.py index 2c5bd73d8a..793b287e77 100644 --- a/gbpservice/nfp/proxy_agent/proxy/proxy.py +++ b/gbpservice/nfp/proxy_agent/proxy/proxy.py @@ -167,7 +167,9 @@ def idle_reset(self): def _wait(self, timeout): if self.type == 'unix': eventlet.sleep(timeout) - self._socket.settimeout(timeout) + self._socket.setblocking(0) + else: + self._socket.settimeout(timeout) def recv(self): self._wait(self._idle_wait) @@ -184,7 +186,9 @@ def recv(self): return None def send(self, data): - self._socket.send(data) + self._socket.setblocking(1) + self._socket.sendall(data) + self._socket.setblocking(0) def close(self): LOG.debug("Closing Socket - %d" % (self.identify())) From ede12d8d8079684601ffb461c0eaf2a4b7568130 Mon Sep 17 00:00:00 2001 From: AkashDeep Date: Thu, 2 Jun 2016 17:10:13 +0530 Subject: [PATCH 04/17] configurator_changes --- gbpservice/nfp/bin/nfp_configurator.ini | 4 ++-- .../nfp/configurator/agents/agent_base.py | 4 ++++ .../nfp/configurator/agents/generic_config.py | 10 +++++++++- gbpservice/nfp/configurator/api/config.py | 3 ++- .../drivers/firewall/vyos/vyos_fw_driver.py | 4 ++++ .../lib/generic_config_constants.py | 2 +- gbpservice/nfp/core/controller.py | 18 +++++++++++------- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/gbpservice/nfp/bin/nfp_configurator.ini b/gbpservice/nfp/bin/nfp_configurator.ini index f6f52abfb0..bcad20de30 100644 --- a/gbpservice/nfp/bin/nfp_configurator.ini +++ b/gbpservice/nfp/bin/nfp_configurator.ini @@ -12,10 +12,10 @@ kombu_reconnect_delay=1.0 rabbit_use_ssl=False rabbit_virtual_host=/ -workers=1 +workers=2 modules_dir=gbpservice.nfp.configurator.modules reportstate_interval=10 -periodic_interval=9 +periodic_interval=2 log_forward_ip_address= log_forward_port=514 diff --git a/gbpservice/nfp/configurator/agents/agent_base.py b/gbpservice/nfp/configurator/agents/agent_base.py index 810b2d6a44..7ce3768237 100644 --- a/gbpservice/nfp/configurator/agents/agent_base.py +++ b/gbpservice/nfp/configurator/agents/agent_base.py @@ -183,6 +183,10 @@ def process_batch(self, ev): result = getattr(driver, method)(context, resource_data) else: result = getattr(driver, method)(**resource_data) + ''' + # [AKASH] + result = const.SUCCESS + ''' success = True if result == 'SUCCESS' else False except Exception as err: result = ("Failed to process %s request. %s" % diff --git a/gbpservice/nfp/configurator/agents/generic_config.py b/gbpservice/nfp/configurator/agents/generic_config.py index 199d4c0c63..79ffc213c8 100644 --- a/gbpservice/nfp/configurator/agents/generic_config.py +++ b/gbpservice/nfp/configurator/agents/generic_config.py @@ -68,6 +68,7 @@ def _send_event(self, context, resource_data, event_id, event_key=None): arg_dict = {'context': context, 'resource_data': resource_data} ev = self.sc.new_event(id=event_id, data=arg_dict, key=event_key) + self.sc.post_event(ev) def configure_interfaces(self, context, resource_data): @@ -222,6 +223,13 @@ def handle_event(self, ev): return # Process HM poll events elif ev.id == gen_cfg_const.EVENT_CONFIGURE_HEALTHMONITOR: + ''' + # [AKASH] + result = common_const.SUCCESS + notification_data = self._prepare_notification_data(ev, result) + self.notify._notification(notification_data) + return + ''' resource_data = ev.data.get('resource_data') periodicity = resource_data.get('periodicity') if periodicity == gen_cfg_const.INITIAL: @@ -273,7 +281,7 @@ def _process_event(self, ev): notification_data = self._prepare_notification_data(ev, result) # self.sc.poll_event_done(ev) self.notify._notification(notification_data) - return STOP_POLLING + return STOP_POLLING elif resource_data.get('periodicity') == gen_cfg_const.FOREVER: if result == common_const.FAILED: """If health monitoring fails continuously for 5 times diff --git a/gbpservice/nfp/configurator/api/config.py b/gbpservice/nfp/configurator/api/config.py index 28498d2070..f0d45757c6 100644 --- a/gbpservice/nfp/configurator/api/config.py +++ b/gbpservice/nfp/configurator/api/config.py @@ -48,7 +48,8 @@ 'logfile': { 'class': 'logging.FileHandler', 'filename': '/var/log/nfp/nfp_pecan.log', - 'level': 'INFO' + 'level': 'INFO', + 'formatter': 'simple' } }, 'formatters': { diff --git a/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py b/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py index 6ac434df54..78a88f05d3 100644 --- a/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py +++ b/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py @@ -564,6 +564,10 @@ def create_firewall(self, context, firewall, host): " %r. URL: %s" % (firewall['id'], firewall['tenant_id'], url)) LOG.info(msg) data = jsonutils.dumps(firewall) + ''' + # [AKASH] + return const.STATUS_ACTIVE + ''' try: resp = requests.post(url, data, timeout=self.timeout) except requests.exceptions.ConnectionError as err: diff --git a/gbpservice/nfp/configurator/lib/generic_config_constants.py b/gbpservice/nfp/configurator/lib/generic_config_constants.py index 8018a7a10f..3ea05a7d59 100644 --- a/gbpservice/nfp/configurator/lib/generic_config_constants.py +++ b/gbpservice/nfp/configurator/lib/generic_config_constants.py @@ -22,4 +22,4 @@ MAX_FAIL_COUNT = 12 # 5 secs delay * 12 = 60 secs INITIAL = 'initial' FOREVER = 'forever' -INITIAL_HM_RETRIES = 24 # 5 secs delay * 24 = 120 secs +INITIAL_HM_RETRIES = 90 # 5 secs delay * 24 = 120 secs diff --git a/gbpservice/nfp/core/controller.py b/gbpservice/nfp/core/controller.py index 36764cccc0..c7695fce52 100644 --- a/gbpservice/nfp/core/controller.py +++ b/gbpservice/nfp/core/controller.py @@ -345,15 +345,19 @@ def get_stashed_events(self): """ events = [] if self._process_name == 'distributor-process': + maxx = 5 # wait sometime for first event in the queue timeout = 0.1 - try: - event = self._stashq.get(timeout=timeout) - self.decompress(event) - events.append(event) - timeout = 0 - except Queue.Empty: - pass + while maxx: + try: + event = self._stashq.get(timeout=timeout) + self.decompress(event) + events.append(event) + timeout = 0 + maxx -= 1 + except Queue.Empty: + maxx = 0 + pass else: LOG.error("worker cannot pull stashed events") return events From d49491c0c0f1864961e40b70c3f288ffc390bb41 Mon Sep 17 00:00:00 2001 From: mak Date: Thu, 2 Jun 2016 17:44:21 +0530 Subject: [PATCH 05/17] corrected to use greenpool instead of nfp.core.threadpool --- .../ncp/node_drivers/nfp_node_driver.py | 78 +++++++++---------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py index 66a0ef58fe..e5d991e59e 100644 --- a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py +++ b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py @@ -14,6 +14,7 @@ # limitations under the License. import eventlet +from eventlet import greenpool from keystoneclient import exceptions as k_exceptions from keystoneclient.v2_0 import client as keyclient from neutron._i18n import _LE @@ -38,7 +39,6 @@ from gbpservice.nfp.common import constants as nfp_constants from gbpservice.nfp.common import topics as nfp_rpc_topics -from gbpservice.nfp.core import threadpool as core_tp NFP_NODE_DRIVER_OPTS = [ @@ -61,7 +61,6 @@ LOG = logging.getLogger(__name__) -thread_pool = core_tp.ThreadPool() class InvalidServiceType(exc.NodeCompositionPluginBadRequest): message = _("The NFP Node driver only supports the services " "VPN, Firewall and LB in a Service Chain") @@ -229,8 +228,9 @@ class NFPNodeDriver(driver_base.NodeDriverBase): def __init__(self): super(NFPNodeDriver, self).__init__() self._lbaas_plugin = None - self.nodes_count = None - self.thread_list = [] + self.thread_pool = greenpool.GreenPool(10) + self.active_threads = [] + self.sc_node_count = 0 @property def name(self): @@ -344,13 +344,18 @@ def create(self, context): self._set_node_instance_network_function_map( context.plugin_session, context.current_node['id'], context.instance['id'], network_function_id) - th = thread_pool.dispatch(self._create_per_node_perf, context, network_function_id) + + # Check for NF status in a separate thread + gth = self.thread_pool.spawn(self._create_per_node_perf, + context, network_function_id) + + self.active_threads.append(gth) self.thread_list.append(th) - self.nodes_count -= 1 - if not self.nodes_count: - for th in self.thread_list: - th.wait() + # At last wait for the threads to complete, success/failure/timeout + if len(self.active_threads) == self.sc_node_count: + for gth in self.active_threads: + gth.wait() def update(self, context): context._plugin_context = self._get_resource_owner_context( @@ -604,8 +609,18 @@ def _get_service_targets(self, context): {'service_type': service_type}) raise Exception("Service Targets are not created for the Node") - service_target_info = {'provider_ports': [], 'provider_subnet': None, 'provider_pts': [], 'provider_pt_objs': [], 'provider_ptg': [], - 'consumer_ports': [], 'consumer_subnet': None, 'consumer_pts': [], 'consumer_pt_objs': [], 'consumer_ptg': []} + service_target_info = { + 'provider_ports': [], + 'provider_subnet': None, + 'provider_pts': [], + 'provider_pt_objs': [], + 'provider_ptg': [], + 'consumer_ports': [], + 'consumer_subnet': None, + 'consumer_pts': [], + 'consumer_pt_objs': [], + 'consumer_ptg': []} + for service_target in provider_service_targets: policy_target = context.gbp_plugin.get_policy_target( context.plugin_context, service_target.policy_target_id) @@ -648,8 +663,7 @@ def _is_node_order_in_spec_supported(self, context): for spec in current_specs: node_list.extend(spec['nodes']) - #[AKASH] - self.nodes_count = len(node_list) + self.sc_node_count = len(node_list) for node_id in node_list: node_info = context.sc_plugin.get_servicechain_node( context.plugin_context, node_id) @@ -673,7 +687,9 @@ def _is_node_order_in_spec_supported(self, context): node_order=allowed_chain_combinations) def _create_network_function(self, context): - ''' + """ + nfp_create_nf_data :- + {'resource_owner_context': <>, 'service_chain_instance': <>, 'service_chain_node': <>, @@ -685,7 +701,8 @@ def _create_network_function(self, context): 'management_ptg_id': <>, 'network_function_mode': nfp_constants.GBP_MODE, } - ''' + + """ nfp_create_nf_data = {} sc_instance = context.instance @@ -718,12 +735,14 @@ def _create_network_function(self, context): consumer_pt = None consumer_ptg = None consumer_ports = None + if service_targets['consumer_pt_objs']: consumer_pt = service_targets.get('consumer_pt_objs', [None])[0] if service_targets['consumer_ptg']: consumer_ptg = service_targets.get('consumer_ptg', [None])[0] if service_targets['consumer_ports']: consumer_ports = service_targets.get('consumer_ports', [None])[0] + consumer = { 'pt': consumer_pt, 'ptg': consumer_ptg, @@ -751,34 +770,7 @@ def _create_network_function(self, context): 'management': management, 'management_ptg_id': sc_instance['management_ptg_id'], 'network_function_mode': nfp_constants.GBP_MODE} - ''' - port_info = [] - if service_targets.get('provider_pts'): - # Device case, for Base mode ports won't be available. - port_info = [ - { - 'id': service_targets['provider_pts'][0], - 'port_model': nfp_constants.GBP_PORT, - 'port_classification': nfp_constants.PROVIDER, - } - ] - if service_targets.get('consumer_ports'): - port_info.append({ - 'id': service_targets['consumer_pts'][0], - 'port_model': nfp_constants.GBP_PORT, - 'port_classification': nfp_constants.CONSUMER, - }) - network_function = { - 'tenant_id': context.provider['tenant_id'], - 'service_chain_id': sc_instance['id'], - 'service_id': context.current_node['id'], - 'service_profile_id': context.current_profile['id'], - 'management_ptg_id': sc_instance['management_ptg_id'], - 'service_config': context.current_node.get('config'), - 'port_info': port_info, - 'network_function_mode': nfp_constants.GBP_MODE, - } - ''' + return self.nfp_notifier.create_network_function( context.plugin_context, network_function=nfp_create_nf_data)['id'] From 06ecaedef1a26bf141af4bd190636e6781a4875c Mon Sep 17 00:00:00 2001 From: mak Date: Thu, 2 Jun 2016 21:02:30 +0530 Subject: [PATCH 06/17] Separated out optimized create path from others --- gbpservice/nfp/core/controller.py | 1 + gbpservice/nfp/core/task.py | 68 +++ .../coal/networking/nfp_gbp_network_driver.py | 3 +- .../networking/nfp_neutron_network_driver.py | 2 - .../config_drivers/heat_driver.py | 162 ++++--- .../drivers/orchestration_driver.py | 403 ++++++------------ .../modules/device_orchestrator.py | 249 ++++------- .../modules/service_orchestrator.py | 167 +++----- 8 files changed, 450 insertions(+), 605 deletions(-) create mode 100644 gbpservice/nfp/core/task.py diff --git a/gbpservice/nfp/core/controller.py b/gbpservice/nfp/core/controller.py index c7695fce52..0e0d15be7b 100644 --- a/gbpservice/nfp/core/controller.py +++ b/gbpservice/nfp/core/controller.py @@ -345,6 +345,7 @@ def get_stashed_events(self): """ events = [] if self._process_name == 'distributor-process': + # return at max 5 events maxx = 5 # wait sometime for first event in the queue timeout = 0.1 diff --git a/gbpservice/nfp/core/task.py b/gbpservice/nfp/core/task.py new file mode 100644 index 0000000000..c42ad34937 --- /dev/null +++ b/gbpservice/nfp/core/task.py @@ -0,0 +1,68 @@ +# 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 gbpservice.nfp.core import threadpool as core_tp + +class InUse(Exception): + + """Exception raised when same executor is fired twice or jobs + added after executor is fired. + """ + pass + +def _check_in_use(f): + def wrapped(self, *args, **kwargs): + if f.fired: + raise InUse("Executor in use") + return f(self, *args, **kwargs) + return wrapped + + +class TaskExecutor(object): + def __init__(self, jobs=0): + if not jobs: + self.thread_pool = core_tp.ThreadPool() + else: + self.thread_pool = core_tp.ThreadPool(thread_pool_size=jobs) + + self.pipe_line = [] + self.fired = False + + @check_in_use + def add_job(id, func, *args, **kwargs): + result_store = kwargs.pop('result_store', None) + job = { + 'id':id, 'method': func, 'args': args, + 'kwargs': kwargs, 'result_store':result_store } + self.pipe_line.append(job) + + def _complete(self): + self.pipe_line = [] + self.fired = False + + @check_in_use + def fire(self): + self.fired = True + for job in self.pipe_line: + th = self.thread_pool.dispatch(job['method'], *job['args'], **job['kwargs']) + job['thread'] = th + + for job in self.pipe_line: + result = job['thread'].wait() + job.pop('thread') + job['result'] = result + if job['result_store']: + job['result_store']['result'] = result + + done_jobs = self.pipe_line[:] + self._complete() + return done_jobs diff --git a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py index 38e66ce850..e0a257a9b3 100644 --- a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py +++ b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py @@ -66,8 +66,7 @@ def set_promiscuos_mode(self, token, port_id): super(NFPGBPNetworkDriver, self).set_promiscuos_mode(token, port_id) self.network_handler = openstack_driver.GBPClient(self.config) - def set_promiscuos_mode_perf(self, token, port_id): - # port_id = self.get_port_id(token, port_id) + def set_promiscuos_mode_v1(self, token, port_id): self.network_handler = openstack_driver.NeutronClient(self.config) super(NFPGBPNetworkDriver, self).set_promiscuos_mode(token, port_id) self.network_handler = openstack_driver.GBPClient(self.config) diff --git a/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py b/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py index d18ce93e2b..e9f59e6805 100644 --- a/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py +++ b/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py @@ -38,7 +38,6 @@ def update_port(self, token, port_id, port): port = self.network_handler.update_port(token, port_id, port) return port['port'] - #[<--PERF] def get_port_and_subnet_details(self, token, port_id): port = self.network_handler.get_port(token, port_id) @@ -55,7 +54,6 @@ def get_port_and_subnet_details(self, token, port_id): gateway_ip = subnet['subnet']['gateway_ip'] return (ip, mac, cidr, gateway_ip, port, subnet) - #[-->PERF] def get_port_details(self, token, port_id): port = self.network_handler.get_port(token, port_id) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index f5450c9162..9dacf3f461 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -99,14 +99,12 @@ def __init__(self, config): self.neutron_client = NeutronClient(config) # self.resource_owner_tenant_id = None - #[<--PERF] keystone_conf = cfg.CONF.keystone_authtoken keystone_version = keystone_conf.auth_version self.v2client = self.keystoneclient._get_v2_keystone_admin_client() self.admin_id = self.v2client.users.find(name=keystone_conf.admin_user).id self.admin_role = self._get_role_by_name(self.v2client, "admin", keystone_version) self.heat_role = self._get_role_by_name(self.v2client, "heat_stack_owner", keystone_version) - #[-->PERF] ''' @@ -141,16 +139,13 @@ def _resource_owner_tenant_id(self): def _get_resource_owner_context(self): if cfg.CONF.heat_driver.is_service_admin_owned: - #[<--PERF] tenant_id = None - # tenant_id = self._resource_owner_tenant_id() user, pwd, tenant_name, auth_url =\ self.keystoneclient.get_keystone_creds() auth_token = self.keystoneclient.get_scoped_keystone_token( user, pwd, tenant_name, tenant_id) tenant_id = self.keystoneclient.get_tenant_id(auth_token, tenant_name) - #[-->PERF] return auth_token, tenant_id def _get_role_by_name(self, keystone_client, name, keystone_version): @@ -189,29 +184,7 @@ def _assign_admin_user_to_project(self, project_id): keystone_version = keystone_conf.auth_version if keystone_version == 'v2.0': - #[<--PERF] return self._assign_admin_user_to_project_v2(project_id) - ''' - v2client = self.keystoneclient._get_v2_keystone_admin_client() - admin_id = v2client.users.find(name=keystone_conf.admin_user).id - admin_role = self._get_role_by_name(v2client, "admin", - keystone_version) - allocated_role_names = self.get_allocated_roles( - v2client, admin_id, project_id) - - if admin_role: - if admin_role.name not in allocated_role_names: - v2client.roles.add_user_role( - admin_id, admin_role.id, tenant=project_id) - - heat_role = self._get_role_by_name(v2client, "heat_stack_owner", - keystone_version) - if heat_role: - if heat_role.name not in allocated_role_names: - v2client.roles.add_user_role(admin_id, heat_role.id, - tenant=project_id) - ''' - #[-->PERF] else: v3client = self.keystoneclient._get_v3_keystone_admin_client() admin_id = v3client.users.find(name=keystone_conf.admin_user).id @@ -487,8 +460,6 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) consumer_eps = service_details['consuming_external_policies'] - #_, consumer_eps = self._get_consumers_for_chain(auth_token, provider) - if (consumer is None) and (consumer_eps is None): return None @@ -1367,7 +1338,44 @@ def _wait_for_stack_operation_complete(self, heatclient, stack_id, action, 'stack_owner': stack.stack_owner}) return None - def is_config_complete(self, nfp_context): + def is_config_complete(self, stack_id, tenant_id, + network_function_details): + success_status = "COMPLETED" + failure_status = "ERROR" + intermediate_status = "IN_PROGRESS" + auth_token, resource_owner_tenant_id =\ + self._get_resource_owner_context() + heatclient = self._get_heat_client(resource_owner_tenant_id, + tenant_id=tenant_id) + if not heatclient: + return failure_status + try: + stack = heatclient.get(stack_id) + if stack.stack_status == 'DELETE_FAILED': + return failure_status + elif stack.stack_status == 'CREATE_COMPLETE': + self.loadbalancer_post_stack_create(network_function_details) + return success_status + elif stack.stack_status == 'UPDATE_COMPLETE': + return success_status + elif stack.stack_status == 'DELETE_COMPLETE': + LOG.info(_LI("Stack %(stack)s is deleted"), + {'stack': stack_id}) + return failure_status + elif stack.stack_status == 'CREATE_FAILED': + return failure_status + elif stack.stack_status == 'UPDATE_FAILED': + return failure_status + elif stack.stack_status not in [ + 'UPDATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', + 'DELETE_IN_PROGRESS']: + return intermediate_status + except Exception: + LOG.exception(_LE("Retrieving the stack %(stack)s failed."), + {'stack': stack_id}) + return failure_status + + def check_config_complete(self, nfp_context): token = nfp_context['resource_owner_context']['auth_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] @@ -1377,10 +1385,6 @@ def is_config_complete(self, nfp_context): failure_status = "ERROR" intermediate_status = "IN_PROGRESS" - ''' - auth_token, resource_owner_tenant_id =\ - self._get_resource_owner_context() - ''' timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) if timeout_seconds: timeout_mins = timeout_mins + 1 @@ -1405,14 +1409,6 @@ def is_config_complete(self, nfp_context): if stack.stack_status == 'DELETE_FAILED': return failure_status elif stack.stack_status == 'CREATE_COMPLETE': - ''' - if nfp_context: - service_type = nfp_context['nfp_service_data']['service_details']['service_type'] - if service_type.lower() == pconst.LOADBALANCER.lower(): - self.loadbalancer_post_stack_create(network_function_details) - else: - self.loadbalancer_post_stack_create(network_function_details) - ''' return success_status elif stack.stack_status == 'UPDATE_COMPLETE': return success_status @@ -1466,23 +1462,6 @@ def is_config_delete_complete(self, stack_id, tenant_id): {'stack': stack_id}) return failure_status - def get_heat_client_perf(self, owner_tenant, provider_tenant, result): - heatclient = self._get_heat_client(owner_tenant, tenant_id=provider_tenant, assign_admin=True) - result['result'] = heatclient - - def update_node_config_perf(self, auth_token, provider_tenant_id, service_profile, - service_chain_node, service_chain_instance, provider, - consumer_port, network_function, - provider_port, mgmt_ip, consumer, service_details, result): - stack_template, stack_params = self._update_node_config( - auth_token, provider_tenant_id, service_profile, - service_chain_node, service_chain_instance, provider, - consumer_port, network_function, - provider_port, mgmt_ip=mgmt_ip, consumer=consumer, service_details=service_details) - result['stack_template'] = stack_template - result['stack_params'] = stack_params - - def get_service_details_from_nfp_context(self, nfp_context): network_function = nfp_context['network_function'] network_function_instance = nfp_context['network_function_instance'] @@ -1520,10 +1499,66 @@ def get_service_details_from_nfp_context(self, nfp_context): 'consuming_external_policies': service_details['consuming_external_policies'] } + def apply_config(self, network_function_details): + service_details = self.get_service_details(network_function_details) + service_profile = service_details['service_profile'] + service_chain_node = service_details['servicechain_node'] + service_chain_instance = service_details['servicechain_instance'] + provider = service_details['policy_target_group'] + provider = service_details['provider_ptg'] + consumer = service_details['consumer_ptg'] + consumer_port = service_details['consumer_port'] + provider_port = service_details['provider_port'] + mgmt_ip = service_details['mgmt_ip'] + + service_details = transport.parse_service_flavor_string( + service_profile['service_flavor']) + + auth_token, resource_owner_tenant_id =\ + self._get_resource_owner_context() + provider_tenant_id = provider['tenant_id'] + heatclient = self._get_heat_client(resource_owner_tenant_id, + tenant_id=provider_tenant_id) + if not heatclient: + return None + stack_name = ("stack_" + service_chain_instance['name'] + + service_chain_node['name'] + + service_chain_instance['id'][:8] + + service_chain_node['id'][:8] + '-' + + time.strftime("%Y%m%d%H%M%S")) + # Heat does not accept space in stack name + stack_name = stack_name.replace(" ", "") + stack_template, stack_params = self._update_node_config( + auth_token, provider_tenant_id, service_profile, + service_chain_node, service_chain_instance, provider, + consumer_port, network_function_details['network_function'], + provider_port, mgmt_ip=mgmt_ip, consumer=consumer) + + if not stack_template and not stack_params: + return None + + try: + stack = heatclient.create(stack_name, stack_template, stack_params) + except Exception as err: + LOG.error(_LE("Heat stack creation failed for template : " + "%(template)s and stack parameters : %(params)s " + "with Error: %(error)s") % + {'template': stack_template, 'params': stack_params, + 'error': err}) + return None + + stack_id = stack['stack']['id'] + LOG.info(_LI("Created stack with ID %(stack_id)s and " + "name %(stack_name)s for provider PTG %(provider)s"), + {'stack_id': stack_id, 'stack_name': stack_name, + 'provider': provider['id']}) + + return stack_id + - def apply_config(self, nfp_context): + def apply_heat_config(self, nfp_context): service_details = self.get_service_details_from_nfp_context(nfp_context) - # service_details = self.get_service_details(network_function_details) + network_function = nfp_context['network_function'] service_profile = service_details['service_profile'] service_chain_node = service_details['servicechain_node'] @@ -1534,11 +1569,6 @@ def apply_config(self, nfp_context): provider_port = service_details['provider_port'] mgmt_ip = service_details['mgmt_ip'] - ''' - if service_profile: - service_details = transport.parse_service_flavor_string( - service_profile['service_flavor']) - ''' token = nfp_context['resource_owner_context']['auth_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index e280b3b972..6fdfefb6c9 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -97,22 +97,7 @@ def _get_setup_mode(self, config): def _get_admin_tenant_id(self, token=None): return self.identity_handler.get_admin_tenant_id(token) - ''' - try: - (dummy, - dummy, - admin_tenant_name, - dummy) = self.identity_handler.get_keystone_creds() - if not token: - token = self.identity_handler.get_admin_token() - admin_tenant_id = self.identity_handler.get_tenant_id( - token, - admin_tenant_name) - return admin_tenant_id - except Exception: - LOG.error(_LE("Failed to get admin's tenant ID")) - raise - ''' + def _get_token(self, device_data_token): try: @@ -283,7 +268,7 @@ def _get_vendor_data(self, device_data, image_name): return None return vendor_data - def _get_vendor_data_perf(self, token, admin_tenant_id, image_name, device_data): + def _get_vendor_data_v1(self, token, admin_tenant_id, image_name, device_data): try: metadata = self.compute_handler_nova.get_image_metadata( token, @@ -333,9 +318,9 @@ def _update_vendor_data(self, device_data, token=None): % (image_name)) - def _update_vendor_data_perf(self, token, admin_tenant_id, image_name, device_data): + def _update_vendor_data_v1(self, token, admin_tenant_id, image_name, device_data): try: - vendor_data = self._get_vendor_data_perf(token, admin_tenant_id, image_name, device_data) + vendor_data = self._get_vendor_data_v1(token, admin_tenant_id, image_name, device_data) LOG.info(_LI("Vendor data, specified in image: %(vendor_data)s"), {'vendor_data': vendor_data}) if vendor_data: @@ -396,16 +381,9 @@ def get_network_function_device_sharing_info(self, device_data): ): raise exceptions.IncompleteData() - #[<--PERF] - ''' - image_name = self._get_image_name(device_data) - if image_name: - self._update_vendor_data(device_data, - device_data.get('token')) - ''' - #[PERF-->] if not self._is_device_sharing_supported(): return None + return { 'filters': { 'tenant_id': [device_data['tenant_id']], @@ -470,10 +448,10 @@ def select_network_function_device(self, devices, device_data): return device return None - def get_image_id(self, nova, token, admin_tenant_id, image_name, result): + def get_image_id(self, nova, token, admin_tenant_id, image_name): try: image_id = nova.get_image_id(token, admin_tenant_id, image_name) - result['image_id'] = image_id + return image_id except Exception as e: LOG.error("Get image id failed !!") @@ -556,29 +534,24 @@ def create_network_function_device(self, device_data, raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) + executor = core_task.TaskExecutor(jobs=3) - thread_pool = core_tp.ThreadPool() - image_name = self._get_image_name(device_data) + image_id_result = {} - ''' - token = self._get_token(device_data.get('token')) - if not token: - return None + executor.add_job('UPDATE_VENDOR_DATA', + self._update_vendor_data_v1, + token, admin_tenant_id, image_name, device_data) + executor.add_job('GET_INTERFACES_FOR_DEVICE_CREATE', + self._get_interfaces_for_device_create, + token, admin_tenant_id, network_handler, device_data) + executor.add_job('GET_IMAGE_ID', + self.get_image_id, + self.compute_handler_nova, token, admin_tenant_id, + image_name, result_store=image_id_result) - admin_tenant_id = self._get_admin_tenant_id(token=token) - ''' - token = device_data['token'] - admin_tenant_id = device_data['admin_tenant_id'] - th1= thread_pool.dispatch(self._update_vendor_data_perf, token, admin_tenant_id, image_name, device_data) - th2 = thread_pool.dispatch(self._get_interfaces_for_device_create, token, admin_tenant_id, network_handler, device_data) - image_id_result = {} - th3 = thread_pool.dispatch(self.get_image_id, self.compute_handler_nova, token, admin_tenant_id, image_name, image_id_result) + completed = executor.fire() - th1.wait() - th2.wait() - th3.wait() - interfaces = device_data.pop('interfaces', None) if not interfaces: LOG.exception(_LE('Failed to get interfaces for device creation.' @@ -589,7 +562,7 @@ def create_network_function_device(self, device_data, self._increment_stats_counter('management_interfaces', by=len(interfaces)) - image_id = image_id_result.get('image_id', None) + image_id = image_id_result.get('result', None) if not image_id: self._increment_stats_counter('image_details_get_failures') LOG.error(_LE('Failed to get image id for device creation.' @@ -613,13 +586,7 @@ def create_network_function_device(self, device_data, advance_sharing_interfaces = [] try: for interface in interfaces: - #[<--PERF] - ''' - port_id = network_handler.get_port_id(token, interface['id']) - interfaces_to_attach.append({'port': port_id})\ - ''' - interfaces_to_attach.append({'port': interface['port_id']}) - #[PERF-->] + interfaces_to_attach.append({'port': interface['port_id']}) if not self.supports_hotplug: if self.setup_mode.get(nfp_constants.NEUTRON_MODE): @@ -669,18 +636,24 @@ def create_network_function_device(self, device_data, return None instance_name = device_data['name'] - instance_id_result = {} - th1 = thread_pool.dispatch(self.create_instance, self.compute_handler_nova, - token, admin_tenant_id, image_id, flavor, - interfaces_to_attach, instance_name, instance_id_result) - port_details_result = {} - th2 = thread_pool.dispatch(self.get_neutron_port_details, network_handler, token, - management_interface['port_id'], port_details_result) - th1.wait() - th2.wait() + executor.add_job('CREATE_INSTANCE', + self.create_instance, + self.compute_handler_nova, + token, admin_tenant_id, flavor, + interfaces_to_attach, instance_name, + result_store = instance_id_result) + + + executor.add_job('GET_NEUTRON_PORT_DETAILS', + self.get_neutron_port_details, + network_handler, token, + management_interface['port_id'], + result_store = port_details_result) + + completed = executor.fire() instance_id = instance_id_result.get('result', None) if not instance_id: @@ -864,12 +837,6 @@ def get_network_function_device_status(self, device_data, return device['status'] - def set_promiscuos_mode(self, network_handler, token, port_id): - network_handler.set_promiscuos_mode_perf(token, port_id) - - def attach_interface(self, nova, token, admin_tenant_id, instance_id, port_id): - nova.attach_interface(token, admin_tenant_id, instance_id, port_id) - @_set_network_handler def plug_network_function_device_interfaces(self, device_data, network_handler=None): @@ -914,15 +881,6 @@ def plug_network_function_device_interfaces(self, device_data, raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) - - #[<--PERF] - #This is already done in "create_network_function_device method of this class. - ''' - image_name = self._get_image_name(device_data) - if image_name: - self._update_vendor_data(device_data) - ''' - #[-->PERF] token = device_data['token'] tenant_id = device_data['tenant_id'] @@ -959,68 +917,21 @@ def plug_network_function_device_interfaces(self, device_data, elif self.setup_mode.get(nfp_constants.NEUTRON_MODE): pass else: - thread_pool = core_tp.ThreadPool() - threads = [] + executor = core_task.TaskExecutor(jobs=10) + for port in device_data['ports']: service_type = device_data['service_details']['service_type'].lower() if service_type == nfp_constants.FIREWALL.lower(): - th = thread_pool.dispatch(self.set_promiscuos_mode, network_handler, token, port['id']) - threads.append(th) - port_id = port['id'] - th = thread_pool.dispatch(self.attach_interface, self.compute_handler_nova, token, tenant_id, device_data['id'], port_id) - threads.append(th) + executor.add_job('SET_PROMISCUOS_MODE', + network_handler.set_promiscuos_mode, + token, port['id']) + executor.add_job('ATTACH_INTERFACE', + self.compute_handler_nova.attach_interface, + token, tenant_id, device_data['id'], + port['id']) + + executor.fire() - for th in threads: - th.wait() - - """ - for port in device_data['ports']: - if port['port_classification'] == nfp_constants.PROVIDER: - if ( - device_data['service_details'][ - 'service_type'].lower() - in [nfp_constants.FIREWALL.lower()] - ): - #network_handler.set_promiscuos_mode(token, - # port['id']) - eventlet.spawn_n(self.set_promiscuos_mode, network_handler, token, port['id']) - #[<--PERF] - # port_id = network_handler.get_port_id(token, - # port['id']) - port_id = port['port_id'] - #[-->PERF] - eventlet.spawn_n(self.attach_interface, self.compute_handler_nova, token, admin_tenant_id, device_data['id'], port_id) - ''' - self.compute_handler_nova.attach_interface( - token, - self._get_admin_tenant_id(token=token), - device_data['id'], - port_id) - ''' - break - for port in device_data['ports']: - if port['port_classification'] == nfp_constants.CONSUMER: - if ( - device_data['service_details'][ - 'service_type'].lower() - in [nfp_constants.FIREWALL.lower()] - ): - network_handler.set_promiscuos_mode(token, - port['id']) - - #[<--PERF] - # port_id = network_handler.get_port_id(token, - # port['id']) - port_id = port['port_id'] - #[-->PERF] - - self.compute_handler_nova.attach_interface( - token, - self._get_admin_tenant_id(token=token), - device_data['id'], - port_id) - break - """ except Exception as e: self._increment_stats_counter('interface_plug_failures') LOG.error(_LE('Failed to plug interface(s) to the device.' @@ -1237,117 +1148,9 @@ def get_network_function_device_healthcheck_info(self, device_data): } - def get_neutron_details(self, token, device_port, network_handler): - LOG.info("$$$$$$$$$$$$$$$$$ GET_NEUTRON_PORT_DETAILS $$$$$$$$$$$$$$$$") - try: - neutron_port_id = network_handler.get_port_id(token, device_port['id']) - device_port['port_id'] = neutron_port_id - (ip, mac, cidr, gateway_ip, - port, subnet) = ( - network_handler.get_neutron_port_details(token, device_port['port_id']) - ) - device_port['neutron_info'] = {'ip': ip, - 'mac': mac, - 'cidr': cidr, - 'gateway_ip': gateway_ip, - 'port': port['port'], - 'subnet': subnet['subnet']} - except Exception as e: - import sys - import traceback - exc_type, exc_value, exc_traceback = sys.exc_info() - print traceback.format_exception(exc_type, exc_value, - exc_traceback) - - #wait_obj.set() - - @_set_network_handler - def get_network_function_device_port_info(self, device_data, network_handler=None): - LOG.error("########## DEVICE DATA: %s" %(str(device_data))) - if ( - type(device_data['ports']) is not list or - - any(key not in port - for port in device_data['ports'] - for key in ['id', - 'port_classification', - 'port_model']) - ): - raise exceptions.IncompleteData() - - token = self._get_token(device_data.get('token')) - if not token: - return None - - new_device_ports = [] - threads = [] - thread_pool = core_tp.ThreadPool() - - consumer_device_port = None - provider_device_port = None - - for port in device_data['ports']: - port_classification = port['port_classification'] - if port_classification == nfp_constants.CONSUMER: - consumer_device_port = port - elif port_classification == nfp_constants.PROVIDER: - provider_device_port = port - - th1 = None - th2 = None - if consumer_device_port: - th1 = thread_pool.dispatch(self.get_neutron_details, token, consumer_device_port, network_handler) - if provider_device_port: - th2 = thread_pool.dispatch(self.get_neutron_details, token, provider_device_port, network_handler) - - LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, start") - if th1: - th1.wait() - if th2: - th2.wait() - LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, end") - - ''' - for device_port in device_data['ports']: - th = thread_pool.dispatch(self.get_neutron_details, token, device_port, network_handler) - threads.append(th) - - LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, start") - for thread in threads: - thread.wait() - LOG.info("####### Profile: get_network_function_device_port_info, waiting_for threads to complete, end") - ''' - LOG.info("@@@@@@@ CHECK PORT_INFO for neutron_info: %s" %(device_data['ports'])) - - - """ - neutron_port_id = network_handler.get_port_id(token, device_port['id']) - device_port['port_id'] = neutron_port_id - try: - (ip, mac, cidr, gateway_ip, - port, subnet) = ( - network_handler.get_neutron_port_details(token, device_port['port_id']) - ) - device_port['neutron_info'] = {'ip': ip, - 'mac': mac, - 'cidr': cidr, - 'gateway_ip': gateway_ip, - 'port': port['port'], - 'subnet': subnet['subnet']} - new_device_ports.append(device_port) - except Exception as e: - self._increment_stats_counter('port_details_get_failures') - LOG.error(_LE('@@@@@@ Failed to get provider port details' - ' for get device config info operation')) - raise e - return None - - device_data['ports'] = new_device_ports - """ - @_set_network_handler def get_network_function_device_config_info(self, device_data, - network_handler=None, is_create_request=False): + network_handler=None): """ Get the configuration information for NFD :param device_data: NFD @@ -1374,7 +1177,6 @@ def get_network_function_device_config_info(self, device_data, :raises: exceptions.IncompleteData """ - ''' if ( any(key not in device_data for key in ['service_details', @@ -1398,62 +1200,105 @@ def get_network_function_device_config_info(self, device_data, ): raise exceptions.IncompleteData() - token = device + token = self._get_token(device_data.get('token')) if not token: return None provider_ip = None provider_mac = None provider_cidr = None - provider_gateway_ip = None consumer_ip = None consumer_mac = None consumer_cidr = None consumer_gateway_ip = None - LOG.error("!!!!!!!!!!!!!!!!! DEVICE DATA: %s" %(str(device_data))) - for port in device_data['ports']: if port['port_classification'] == nfp_constants.PROVIDER: try: - #[<--PERF] - if not is_create_request: - (provider_ip, provider_mac, provider_cidr, dummy) = ( - network_handler.get_port_details(token, port['id']) - ) - else: - provider_ip = port['neutron_info']['ip'] - provider_mac = port['neutron_info']['mac'] - provider_cidr = port['neutron_info']['cidr'] - provider_gateway_ip = port['neutron_info']['gateway_ip'] - #[-->PERF] - except Exception as e: + (provider_ip, provider_mac, provider_cidr, dummy) = ( + network_handler.get_port_details(token, port['id']) + ) + except Exception: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get provider port details' ' for get device config info operation')) - raise e return None elif port['port_classification'] == nfp_constants.CONSUMER: try: - #[<--PERF] - if not is_create_request: - (consumer_ip, consumer_mac, consumer_cidr, - consumer_gateway_ip) = ( - network_handler.get_port_details(token, port['id']) - ) - else: - consumer_ip = port['neutron_info']['ip'] - consumer_mac = port['neutron_info']['mac'] - consumer_cidr = port['neutron_info']['cidr'] - consumer_gateway_ip = port['neutron_info']['gateway_ip'] - - except Exception as e: + (consumer_ip, consumer_mac, consumer_cidr, + consumer_gateway_ip) = ( + network_handler.get_port_details(token, port['id']) + ) + except Exception: self._increment_stats_counter('port_details_get_failures') LOG.error(_LE('Failed to get consumer port details' ' for get device config info operation')) - raise e return None - ''' + + return { + 'config': [ + { + 'resource': nfp_constants.INTERFACE_RESOURCE, + 'resource_data': { + 'mgmt_ip': device_data['mgmt_ip_address'], + 'provider_ip': provider_ip, + 'provider_cidr': provider_cidr, + 'provider_interface_index': 2, + 'stitching_ip': consumer_ip, + 'stitching_cidr': consumer_cidr, + 'stitching_interface_index': 3, + 'provider_mac': provider_mac, + 'stitching_mac': consumer_mac, + } + }, + { + 'resource': nfp_constants.ROUTES_RESOURCE, + 'resource_data': { + 'mgmt_ip': device_data['mgmt_ip_address'], + 'source_cidrs': ([provider_cidr, consumer_cidr] + if consumer_cidr + else [provider_cidr]), + 'destination_cidr': consumer_cidr, + 'provider_mac': provider_mac, + 'gateway_ip': consumer_gateway_ip, + 'provider_interface_index': 2 + } + } + ] + } + + + + @_set_network_handler + def get_create_network_function_device_config_info(self, device_data, + network_handler=None): + """ Get the configuration information for NFD + + :param device_data: NFD + :type device_data: dict + + :returns: None -- On Failure + :returns: dict -- It has the following scheme + { + 'config': [ + { + 'resource': 'interfaces', + 'resource_data': { + ... + } + }, + { + 'resource': 'routes', + 'resource_data': { + ... + } + } + ] + } + + :raises: exceptions.IncompleteData + """ + mgmt_ip = device_data.get('mgmt_ip', None) provider_ip = device_data.get('provider_ip', None) provider_mac = device_data.get('provider_mac', None) diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index b4dc0b4458..e33bca3d53 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -53,7 +53,8 @@ def rpc_init(controller, config): def events_init(controller, config, device_orchestrator): events = ['CREATE_NETWORK_FUNCTION_DEVICE', 'DEVICE_SPAWNING', - 'DEVICE_HEALTHY', 'CONFIGURE_DEVICE', + 'DEVICE_HEALTHY', 'HEALTH_MONITOR_COMPLETE', + 'CONFIGURE_DEVICE', 'CREATE_DEVICE_CONFIGURATION', 'DEVICE_CONFIGURED', "DELETE_CONFIGURATION", 'DELETE_NETWORK_FUNCTION_DEVICE', 'DELETE_CONFIGURATION_COMPLETED', 'DEVICE_BEING_DELETED', @@ -79,7 +80,7 @@ def __init__(self, conf, controller): self.conf = conf self._controller = controller self.rpc_event_mapping = { - 'healthmonitor': ['DEVICE_HEALTHY', + 'healthmonitor': ['HEALTH_MONITOR_COMPLETE', 'DEVICE_NOT_REACHABLE', 'DEVICE_NOT_REACHABLE'], 'interfaces': ['DEVICE_CONFIGURED', @@ -224,9 +225,11 @@ def event_method_mapping(self, event_id): "CREATE_NETWORK_FUNCTION_DEVICE": ( self.create_network_function_device), "DEVICE_UP": self.perform_health_check, - "PLUG_INTERFACES": self.plug_interfaces, - "DEVICE_HEALTHY": self.device_healthy, - "CONFIGURE_DEVICE": self.create_device_configuration, + "PLUG_INTERFACES": self.plug_interfaces_v1, + "DEVICE_HEALTHY": self.plug_interfaces, + "HEALTH_MONITOR_COMPLETE": self.device_healthy, + "CONFIGURE_DEVICE": self.configure_device, + "CREATE_DEVICE_CONFIGURATION": self.create_device_configuration, "DEVICE_CONFIGURED": self.device_configuration_complete, "DELETE_NETWORK_FUNCTION_DEVICE": ( @@ -413,15 +416,6 @@ def _create_network_function_device_db(self, device_info, state): device_info['interfaces_in_use'] = 0 device = self.nsf_db.create_network_function_device(self.db_session, device_info) - #[<--PERF] - #Dont need this here. - ''' - mgmt_port_id = device.pop('mgmt_port_id') - mgmt_port_id = self._get_port(mgmt_port_id) - device['mgmt_port_id'] = mgmt_port_id - ''' - #[-->PERF] - if advance_sharing_interfaces: self._create_advance_sharing_interfaces(device, advance_sharing_interfaces) @@ -478,15 +472,7 @@ def _get_device_to_reuse(self, device_data, dev_sharing_info): device_data) return device - def _get_device_data(self, nfd_request, is_create_request=False): - #[<--PERF] - # Check if the context already has device_data - context = nfp_core_context.get_nfp_context() - if context != {} and context['nfp_device_data']: - device_data = context['nfp_device_data'] - return device_data - #[PERF -->] - + def _get_device_data(self, nfd_request): device_data = {} network_function = nfd_request.get('network_function') @@ -507,17 +493,10 @@ def _get_device_data(self, nfd_request, is_create_request=False): network_function_instance['id']) device_data['tenant_id'] = network_function_instance['tenant_id'] - #[<--PERF] - #Are we getting anything more than what is in network_function_instance['port_info'] ? - #Looks like not really. - if is_create_request: - nsi_port_info = network_function_instance['port_info'] - else: - nsi_port_info = [] - for port_id in network_function_instance.pop('port_info'): - port_info = self.nsf_db.get_port_info(self.db_session, port_id) - nsi_port_info.append(port_info) - #[PERF -->] + nsi_port_info = [] + for port_id in network_function_instance.pop('port_info'): + port_info = self.nsf_db.get_port_info(self.db_session, port_id) + nsi_port_info.append(port_info) device_data['ports'] = nsi_port_info @@ -530,13 +509,6 @@ def _get_device_data(self, nfd_request, is_create_request=False): nfp_constants.NEUTRON_MODE) device_data['service_vendor'] = service_details['service_vendor'] - #[<--PERF] - #Store the updated context - if is_create_request: - context['nfp_device_data'] = device_data - nfp_core_context.store_nfp_context(**context) - #[PERF-->] - return device_data def _get_nsf_db_resource(self, resource_name, resource_id): @@ -563,13 +535,16 @@ def _prepare_device_data_from_nfp_context(self, nfp_context): 'id': nfp_context['management_ptg_id'], 'port_model': nfp_constants.GBP_NETWORK } + consumer = nfp_context['consumer'] provider = nfp_context['provider'] ports = [] + if consumer['port']: ports.append({'id': consumer['port']['id'], 'port_classification': consumer['port_classification'], 'port_model': consumer['port_model']}) + if provider['port']: ports.append({'id': provider['port']['id'], 'port_classification': provider['port_classification'], @@ -596,26 +571,26 @@ def create_network_function_device(self, event): new service or it creates new device instance """ - nfd_request = event.data - nfp_context = nfd_request + device = None + nfd_request = event.data + nfp_context = event.data service_details = nfp_context['service_details'] - device = None LOG.info(_LI("Device Orchestrator received create network service " "device request with data %(data)s"), {'data': nfd_request}) - # device_data = self._get_device_data(nfd_request, is_create_request=True) - orchestration_driver = self._get_orchestration_driver( service_details['service_vendor']) + device_data = self._prepare_device_data_from_nfp_context(nfp_context) dev_sharing_info = ( orchestration_driver.get_network_function_device_sharing_info( device_data)) + if dev_sharing_info: device = self._get_device_to_reuse(device_data, dev_sharing_info) if device: @@ -635,6 +610,7 @@ def create_network_function_device(self, event): LOG.info(_LI("No Device exists for sharing, Creating new device," "device request: %(device)s"), {'device': nfd_request}) LOG.info("Prepared device_data %s" %(device_data)) + driver_device_info = ( orchestration_driver.create_network_function_device( device_data)) @@ -658,8 +634,7 @@ def create_network_function_device(self, event): network_function_device = self._create_network_function_device_db(device, 'DEVICE_SPAWNING') - LOG.info("@@@@@@@@@@ DEVICE - %s" %(str(device))) - #[PERF-TODO] Wrong by nfp_db method needs in this format + #[mak: TODO] Wrong by nfp_db method needs in this format network_function_device['mgmt_port_id'] = device['mgmt_port_id'] nfp_context['network_function_device'] = network_function_device @@ -670,57 +645,43 @@ def create_network_function_device(self, event): 'network_function_device_id': device['id'], } - self._create_event(event_id='DEVICE_SPAWNING', event_data=nfp_context, is_poll_event=True, original_event=event) + self._create_event(event_id='DEVICE_CREATED', event_data=device_created_data) @poll_event_desc(event='DEVICE_SPAWNING', spacing=2) def check_device_is_up(self, event): - nfp_context = event.data + service_details= nfp_context['service_details'] network_function_device = nfp_context['network_function_device'] token = nfp_context['resource_owner_context']['auth_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] + device = { 'token': token, 'tenant_id': tenant_id, 'id': network_function_device['id'], 'service_details': service_details} + orchestration_driver = self._get_orchestration_driver( service_details['service_vendor']) + is_device_up = ( orchestration_driver.get_network_function_device_status(device)) - if is_device_up == nfp_constants.ACTIVE: - #[<--PERF] - # Optimized the db update across three function calls - ''' - self._update_network_function_device_db(device, - 'DEVICE_UP') - ''' - - #[<--PERF] - # LOG.info("@@@@@@ Profile: get_network_function_device_port_info, start @@@@") - # orchestration_driver.get_network_function_device_port_info(device) - # LOG.info("@@@@@@ Profile: get_network_function_device_port_info, end @@@@") + if is_device_up == nfp_constants.ACTIVE: # create event DEVICE_UP self._create_event(event_id='DEVICE_UP', event_data=nfp_context) - LOG.info("@@@@@@ Profile: plug_interfaces, start @@@@") self._create_event(event_id='PLUG_INTERFACES', event_data=nfp_context, is_internal_event=True) - LOG.info("@@@@@@ Profile: plug_interfaces, end @@@@") - - - self._update_network_function_device_db(device, 'HEALTH_CHECK_PENDING') - #[-->PERF] return STOP_POLLING elif is_device_up == nfp_constants.ERROR: @@ -736,23 +697,18 @@ def check_device_is_up(self, event): return CONTINUE_POLLING def perform_health_check(self, event): - ''' - #[<--PERF] - nfp_context = event.data - nfp_core_context.store_nfp_context(**nfp_context) - # device = event.data - device = nfp_context['nfp_device_data'] - #[-->PERF] - ''' nfp_context = event.data + service_details = nfp_context['service_details'] network_function_device = nfp_context['network_function_device'] network_function = nfp_context['network_function'] network_function_instance = nfp_context['network_function_instance'] mgmt_ip_address = nfp_context['management']['port']['ip_address'] + # The driver tells which protocol / port to monitor ?? orchestration_driver = self._get_orchestration_driver( service_details['service_vendor']) + device ={ 'id': network_function_device['id'], 'mgmt_ip_address': mgmt_ip_address, @@ -761,6 +717,7 @@ def perform_health_check(self, event): 'network_function_instance_id': network_function_instance['id'], 'nfp_context': nfp_context } + hm_req = ( orchestration_driver.get_network_function_device_healthcheck_info( device)) @@ -769,20 +726,16 @@ def perform_health_check(self, event): event_data=device, is_internal_event=True) return None + self.configurator_rpc.create_network_function_device_config(device, hm_req) LOG.debug("Health Check RPC sent to configurator for device: " "%s with health check parameters: %s" % ( device['id'], hm_req)) - #[<--PERF] - #Dont need to update in DB Here as the next function call for plug interfaces - #will update the db. + device['status'] = 'HEALTH_CHECK_PENDING' - ''' self._update_network_function_device_db(device, 'HEALTH_CHECK_PENDING') - ''' - #[-->PERF] def _get_service_type(self, service_profile_id): admin_token = self.keystoneclient.get_admin_token() @@ -832,32 +785,64 @@ def _prepare_device_data(self, device_info): self._get_advance_sharing_interfaces(device['id'])) return device - #[<--PERF] def device_healthy(self, event): - nfp_context = event.data.get('nfp_context', None) + nfp_context = event.data['nfp_context'] + device = nfp_context['network_function_device'] + self._update_network_function_device_db(device, 'HEALTH_CHECK_COMPLETED') + self._create_event(event_id='DEVICE_ACTIVE', event_data=nfp_context) - self._create_event(event_id='CONFIGURE_DEVICE', + + self._create_event(event_id='CREATE_DEVICE_CONFIGURATION', event_data=nfp_context, is_internal_event=True) - #[-->PERF] def plug_interfaces(self, event, is_event_call=True): + if is_event_call: + device_info = event.data + else: + device_info = event + # Get event data, as configurator sends back only request_info, which + # contains nf_id, nfi_id, nfd_id. + device = self._prepare_device_data(device_info) + self._update_network_function_device_db(device, + 'HEALTH_CHECK_COMPLETED') + orchestration_driver = self._get_orchestration_driver( + device['service_details']['service_vendor']) + _ifaces_plugged_in = ( + orchestration_driver.plug_network_function_device_interfaces( + device)) + if _ifaces_plugged_in: + self._increment_device_interface_count(device) + self._create_event(event_id='CONFIGURE_DEVICE', + event_data=device, + is_internal_event=True) + else: + self._create_event(event_id='DEVICE_CONFIGURATION_FAILED', + event_data=device, + is_internal_event=True) + + + def plug_interfaces_v1(self, event): - #[-->PERF] - # Now, this event is happening in paralell with HEALTHMONITORING, + # In this case, the event will be + # happening in paralell with HEALTHMONITORIN, # so, we should not generate CONFIGURE_DEVICE & should not update # DB with HEALTH_CHECK_COMPLETED. + nfp_context = event.data + service_details = nfp_context['service_details'] network_function_device = nfp_context['network_function_device'] token = nfp_context['resource_owner_context']['auth_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] - # device = nfp_context['nfp_device_data'] - orchestration_driver = self._get_orchestration_driver( - service_details['service_vendor']) + consumer = nfp_context['consumer'] provider = nfp_context['provider'] + + orchestration_driver = self._get_orchestration_driver( + service_details['service_vendor']) + ports = [] if consumer['port']: ports.append({'id': consumer['port']['id'], @@ -884,49 +869,27 @@ def plug_interfaces(self, event, is_event_call=True): device, advance_sharing_ifaces) self._increment_device_interface_count(device) - #[PERF - TODO] - Check how incremented ref count can be updated in DB + #[mak: TODO] - Check how incremented ref count can be updated in DB - ''' - if is_event_call: - device_info = event.data - else: - device_info = event - # Get event data, as configurator sends back only request_info, which - # contains nf_id, nfi_id, nfd_id. - device = self._prepare_device_data(device_info) - self._update_network_function_device_db(device, - 'HEALTH_CHECK_COMPLETED') + def configure_device(self, event): + device = event.data orchestration_driver = self._get_orchestration_driver( device['service_details']['service_vendor']) - - _ifaces_plugged_in, advance_sharing_ifaces = ( - orchestration_driver.plug_network_function_device_interfaces( - device)) - if _ifaces_plugged_in: - if advance_sharing_ifaces: - self._update_advance_sharing_interfaces( - device, - advance_sharing_ifaces) - self._increment_device_interface_count(device) - self._create_event(event_id='CONFIGURE_DEVICE', - event_data=device, - is_internal_event=True) - else: - self._create_event(event_id='DEVICE_CONFIGURATION_FAILED', + config_params = ( + orchestration_driver.get_network_function_device_config_info( + device)) + if not config_params: + self._create_event(event_id='DRIVER_ERROR', event_data=device, is_internal_event=True) - ''' + return None + # Sends RPC to configurator to create generic config + self.configurator_rpc.create_network_function_device_config( + device, config_params) def create_device_configuration(self, event): - ''' - #[<--PERF] - nfp_context = event.data - nfp_core_context.store_nfp_context(**nfp_context) - # device = event.data - device = nfp_context['nfp_device_data'] - #[-->PERF] - ''' nfp_context = event.data + service_details = nfp_context['service_details'] token = nfp_context['resource_owner_context']['auth_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] @@ -953,8 +916,8 @@ def create_device_configuration(self, event): 'consumer_gateway_ip': consumer['subnet']['gateway_ip']}) config_params = ( - orchestration_driver.get_network_function_device_config_info( - device, is_create_request=True)) + orchestration_driver.get_create_network_function_device_config_info( + device)) device.update({ 'id': network_function_device['id'], 'mgmt_ip_address': management['port']['ip_address'], @@ -973,15 +936,8 @@ def create_device_configuration(self, event): device, config_params) def device_configuration_complete(self, event): - ''' - #[<--PERF] - nfp_context = event.data['nfp_context'] - # device_info = event.data - # device = self._prepare_device_data(device_info) - device = nfp_context['nfp_device_data'] - #[-->PERF] - ''' nfp_context = event.data.get('nfp_context', None) + device = nfp_context['network_function_device'] # Change status to active in DB and generate an event DEVICE_ACTIVE @@ -993,23 +949,6 @@ def device_configuration_complete(self, event): "reference count for %(device)s"), {'device_id': device['id'], 'device': device}) - #[<--PERF] - # DEVICE_ACTIVE event is sent paralell to configure device - # so dont need to send here. - ''' - device_created_data = { - 'network_function_id': ( - device['network_function_id']), - 'network_function_instance_id': ( - device['network_function_instance_id']), - 'network_function_device_id': device['id'], - } - # DEVICE_ACTIVE event for NSO. - self._create_event(event_id='DEVICE_ACTIVE', - event_data=device_created_data) - ''' - #[-->PERF] - # Delete path def delete_network_function_device(self, event): delete_nfd_request = event.data @@ -1191,10 +1130,8 @@ def _get_request_info(self, device, operation): 'requester': nfp_constants.DEVICE_ORCHESTRATOR, 'operation': operation, 'logging_context': nfp_logging.get_logging_context(), - #[<--PERF] - #Add so that notifications can work on cached data + # So that notification callbacks can work on cached data 'nfp_context': device.get('nfp_context', None) - #[-->PERF] } nfd_ip = device['mgmt_ip_address'] request_info.update({'device_ip': nfd_ip}) diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 502689ec50..89a55a1507 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -404,13 +404,15 @@ def event_method_mapping(self, event_id): "CONSUMER_ADD": self.consumer_ptg_add_user_config, "CONSUMER_REMOVE": self.consumer_ptg_remove_user_config, "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.check_for_user_config_complete), + self.apply_user_config_in_progress), "DELETE_USER_CONFIG_IN_PROGRESS": ( self.check_for_user_config_deleted), "CONFIG_APPLIED": self.handle_config_applied, @@ -614,6 +616,7 @@ def create_network_function(self, context, network_function_info): admin_token = self.keystoneclient.get_admin_token() admin_tenant_id = self.keystoneclient.get_admin_tenant_id(admin_token) + network_function_info['resource_owner_context']['auth_token'] = admin_token network_function_info['resource_owner_context']['tenant_id'] = admin_tenant_id network_function_info['resource_owner_context']['admin_tenant_id'] = admin_tenant_id @@ -646,6 +649,7 @@ def create_network_function(self, context, network_function_info): 'service_config': service_config_str, 'status': nfp_constants.PENDING_CREATE } + network_function = self.db_handler.create_network_function( self.db_session, network_function) @@ -670,53 +674,19 @@ def create_network_function(self, context, network_function_info): service_config_str) return network_function - ''' - if mode == nfp_constants.GBP_MODE: - management_network_info = { - 'id': network_function_info['management_ptg_id'], - 'port_model': nfp_constants.GBP_NETWORK - } - else: - management_network_info = {} - - port_info = [] - for ele in [consumer, provider]: - port_info.append({'id': ele['pt']['id'], - 'port_model': ele['port_model'], - 'port_classification': ele['port_classification'] - }) - - create_network_function_instance_request = { - 'network_function': network_function, - 'network_function_port_info': port_info, - 'management_network_info': management_network_info, - 'service_type': service_profile['service_type'], - 'service_details': service_details, - 'share_existing_device': False # Extend service profile if needed - } - - #[<--PERF] - nfp_context = {} - nfp_context['nfp_service_data'] = create_network_function_instance_request - nfp_context['nfp_service_data']['network_function_info'] = network_function_info - nfp_context['admin_token'] = admin_token - # Save this context in thread - as "CREATE_NETWORK_FUNCTION_INSTANCE" is internal event" - nfp_core_context.store_nfp_context(**nfp_context) - ##[PERF-->] - ''' - nfp_context = 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 - create_network_function_instance_request = nfp_context # Create and event to perform Network service instance self._create_event('CREATE_NETWORK_FUNCTION_INSTANCE', - event_data=create_network_function_instance_request, + event_data=nfp_context, is_internal_event=True) + nfp_logging.clear_logging_context() return network_function @@ -818,46 +788,21 @@ def create_network_function_instance(self, event): 'share_existing_device': nfp_context['share_existing_device'], 'port_info': port_info, } - nfi_db = self.db_handler.create_network_function_instance( - self.db_session, create_nfi_request) + + network_function_instance = \ + 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, + self._report_logging_info(network_function, + network_function_instance, service_details['service_type'], service_details['service_vendor']) - ''' - request_data['service_details'].update( - service_type=request_data['service_type']) - create_nfd_request = { - 'network_function': request_data['network_function'], - 'network_function_instance': nfi_db, - 'management_network_info': request_data['management_network_info'], - 'service_vendor': ( - request_data['service_details']['service_vendor']), - 'service_details': request_data['service_details'], - 'share_existing_device': request_data['share_existing_device'], - } - - #[<--PERF] - nfi_db['port_info'] = request_data['network_function_port_info'] - nfp_context['nfp_service_data'].update({'port_info': request_data['network_function_port_info']}) - nfp_context['nfp_service_data'].update({'network_function_instance': nfi_db}) - - # Update the thread context - nfp_core_context.store_nfp_context(**nfp_context) - - # Since the CREATE_NETWORK_FUNCTION_DEVICE is not internal event - # Update the context in event. - create_nfd_request['nfp_context'] = nfp_context - #[PERF -->] - ''' - - nfp_context['network_function_instance'] = nfi_db - create_nfd_request = nfp_context + nfp_context['network_function_instance'] = network_function_instance LOG.info(_LI("[Event:CreateService]")) self._create_event('CREATE_NETWORK_FUNCTION_DEVICE', - event_data=create_nfd_request) + event_data=nfp_context) def handle_device_created(self, event): request_data = event.data @@ -870,14 +815,8 @@ def handle_device_created(self, event): return def handle_device_active(self, event): - ''' - #[<--PERF] - nfp_context = event.data - nfp_core_context.store_nfp_context(**nfp_context) - request_data = nfp_context['nfp_device_data'] - # request_data = event.data - ''' nfp_context = event.data + network_function_instance = nfp_context['network_function_instance'] network_function_device = nfp_context['network_function_device'] network_function = nfp_context['network_function'] @@ -895,17 +834,6 @@ def handle_device_active(self, event): network_function_instance['status'] = nfp_constants.ACTIVE network_function_instance['network_function_device_id'] = network_function_device['id'] - ''' - network_function = self.db_handler.get_network_function( - self.db_session, nfi['network_function_id']) - ''' - ''' - nfp_context['nfp_service_data']['network_function_instance']['status'] = nfp_constants.ACTIVE - nfp_context['nfp_service_data']['network_function_instance']['network_function_device_id'] = request_data[ - 'network_function_device_id'] - - network_function = nfp_context['nfp_service_data']['network_function'] - ''' service_config = network_function['service_config'] nfp_core_context.store_nfp_context(nfp_context) @@ -913,17 +841,18 @@ def handle_device_active(self, event): service_config) def apply_user_config(self, event): - #[<--PERF] + request_data = event.data nfp_context = event.data['nfp_context'] + nfp_core_context.store_nfp_context(nfp_context) - #[-->PERF] + network_function = nfp_context['network_function'] - request_data = event.data network_function_details = self.get_network_function_details( network_function['id']) - request_data['heat_stack_id'], heat_client = self.config_driver.apply_config( + request_data['heat_stack_id'], heat_client = self.config_driver.apply_heat_config( nfp_context) # Heat driver to launch stack request_data['network_function_id'] = network_function['id'] + if not request_data['heat_stack_id']: self._create_event('USER_CONFIG_FAILED', event_data=request_data, is_internal_event=True) @@ -931,14 +860,17 @@ def apply_user_config(self, event): LOG.debug("handle_device_active heat_stack_id: %s" % (request_data['heat_stack_id'])) - #[<--PERF] + nfp_context['heat_stack_id'] = request_data['heat_stack_id'] - nfp_context['network_function'].update({'heat_stack_id': request_data['heat_stack_id'], - 'description': network_function['description']}) - self._create_event('APPLY_USER_CONFIG_IN_PROGRESS', + nfp_context['network_function'].update({ + 'heat_stack_id': request_data['heat_stack_id'], + 'description': network_function['description']}) + + self._create_event('CHECK_USER_CONFIG_COMPLETE', event_data=nfp_context, is_poll_event=True, original_event=event) + self.db_handler.update_network_function( self.db_session, network_function['id'], {'heat_stack_id': request_data['heat_stack_id'], @@ -1107,10 +1039,47 @@ def _validate_create_service_input(self, context, create_service_request): required_data=", ".join(missing_keys), request="Create Network Function") + def apply_user_config_in_progress(self, event): + request_data = event.data + config_status = self.config_driver.is_config_complete( + request_data['heat_stack_id'], request_data['tenant_id'], + request_data['network_function_details']) + if config_status == nfp_constants.ERROR: + LOG.info(_LI("NSO: applying user config failed for " + "network function %(network_function_id)s data " + "%(data)s"), {'data': request_data, + 'network_function_id': + request_data['network_function_id']}) + updated_network_function = {'status': nfp_constants.ERROR} + self.db_handler.update_network_function( + self.db_session, + request_data['network_function_id'], + updated_network_function) + self._controller.event_done(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(_LI("NSO: applying user config is successfull moving " + "network function %(network_function_id)s to ACTIVE"), + {'network_function_id': + request_data['network_function_id']}) + self.db_handler.update_network_function( + self.db_session, + request_data['network_function_id'], + updated_network_function) + self._controller.event_done(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 check_for_user_config_complete(self, event): nfp_context = event.data + network_function = nfp_context['network_function'] - config_status = self.config_driver.is_config_complete(nfp_context) + config_status = self.config_driver.check_config_complete(nfp_context) + if config_status == nfp_constants.ERROR: LOG.info(_LI("NSO: applying user config failed for " "network function %(network_function_id)s data " @@ -1582,7 +1551,6 @@ def get_port_info(self, port_id): return None def get_network_function_details(self, network_function_id): - #[<--PERF] network_function = None network_function_instance = None network_function_device = None @@ -1621,7 +1589,6 @@ def get_network_function_details(self, network_function_id): self.db_session, network_function_instance['network_function_device_id'])) network_function_details['network_function_device'] = ( network_function_device) - #[-->PERF] return network_function_details From ade56e7b5d031001dcdbdcc1aeb77722d228023d Mon Sep 17 00:00:00 2001 From: mak Date: Fri, 3 Jun 2016 00:51:14 +0530 Subject: [PATCH 07/17] fixed token related issues --- .../config_drivers/heat_driver.py | 83 ++++++++++--------- .../modules/service_orchestrator.py | 3 +- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index 9dacf3f461..6c6a98c3a3 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -207,6 +207,38 @@ def keystone(self, user, pwd, tenant_name, tenant_id=None): return self.keystoneclient.get_scoped_keystone_token( user, pwd, tenant_name) + def _get_heat_client_v1(self, nfp_context, assign_admin=False): + tenant_id = nfp_context['resource_owner_context']['tenant_id'] + auth_token = nfp_context['resource_owner_context']['auth_token'] + + if assign_admin: + try: + self._assign_admin_user_to_project(tenant_id) + except Exception: + LOG.exception(_LE("Failed to assign admin user to project")) + return None + + user, password, tenant, auth_url =\ + self.keystoneclient.get_keystone_creds() + + timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) + if timeout_seconds: + timeout_mins = timeout_mins + 1 + try: + heat_client = HeatClient( + user, + tenant_id, + cfg.CONF.heat_driver.heat_uri, + password, + auth_token=auth_token, + timeout_mins=timeout_mins) + except Exception: + LOG.exception(_LE("Failed to create heatclient object")) + return None + + return heat_client + + def _get_heat_client(self, resource_owner_tenant_id, tenant_id=None, assign_admin=False): user_tenant_id = tenant_id or resource_owner_tenant_id if assign_admin: @@ -1377,31 +1409,14 @@ def is_config_complete(self, stack_id, tenant_id, def check_config_complete(self, nfp_context): + provider = nfp_context['provider']['ptg'] + token = nfp_context['resource_owner_context']['auth_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] - stack_id = nfp_context['heat_stack_id'] - - success_status = "COMPLETED" - failure_status = "ERROR" - intermediate_status = "IN_PROGRESS" - - timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) - if timeout_seconds: - timeout_mins = timeout_mins + 1 - user, password, tenant, auth_url =\ - self.keystoneclient.get_keystone_creds() - try: - heatclient = HeatClient( - user, - tenant_id, - cfg.CONF.heat_driver.heat_uri, - password, - auth_token=token, - timeout_mins=timeout_mins) - except Exception: - LOG.exception(_LE("Failed to create heatclient object")) - return None + resource_owner_tenant_id = tenant_id + heatclient = self._get_heat_client_v1(resource_owner_tenant_id, + tenant_id=provider['tenant_id']) if not heatclient: return failure_status try: @@ -1571,22 +1586,16 @@ def apply_heat_config(self, nfp_context): token = nfp_context['resource_owner_context']['auth_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] + resource_owner_tenant_id = tenant_id - timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) - if timeout_seconds: - timeout_mins = timeout_mins + 1 - - user, password, tenant, auth_url =\ - self.keystoneclient.get_keystone_creds() - heatclient = HeatClient( - user, - tenant_id, - cfg.CONF.heat_driver.heat_uri, - password, - auth_token=token, - timeout_mins=timeout_mins) - - stack_template, stack_params = self._create_node_config_data(token, tenant_id, + heatclient = self._get_heat_client_v1(resource_owner_tenant_id, + tenant_id=provider['tenant_id'], + assign_admin=True) + if not heatclient: + return None + + stack_template, stack_params = self._create_node_config_data( + token, tenant_id, service_chain_node, service_chain_instance, provider, provider_port, consumer, consumer_port, network_function, mgmt_ip, service_details) diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 89a55a1507..007c02fe49 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -617,8 +617,7 @@ def create_network_function(self, context, network_function_info): admin_token = self.keystoneclient.get_admin_token() admin_tenant_id = self.keystoneclient.get_admin_tenant_id(admin_token) - network_function_info['resource_owner_context']['auth_token'] = admin_token - network_function_info['resource_owner_context']['tenant_id'] = admin_tenant_id + network_function_info['resource_owner_context']['admin_token'] = admin_token network_function_info['resource_owner_context']['admin_tenant_id'] = admin_tenant_id # GBP or Neutron From c988e995d2ef5a2beb25deb2c34f84fd4ac275f1 Mon Sep 17 00:00:00 2001 From: mak Date: Fri, 3 Jun 2016 16:19:20 +0530 Subject: [PATCH 08/17] removed unused variables and methods --- .../plugins/ncp/node_drivers/nfp_node_driver.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py index e5d991e59e..f6136ca221 100644 --- a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py +++ b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py @@ -333,10 +333,6 @@ def validate_update(self, context): service_type=context.current_profile['service_type'], vendor=context.current_profile['vendor']) - def _create_per_node_perf(self, context, network_function_id): - self._wait_for_network_function_operation_completion( - context, network_function_id, operation='create') - def create(self, context): context._plugin_context = self._get_resource_owner_context( context._plugin_context) @@ -346,16 +342,16 @@ def create(self, context): context.instance['id'], network_function_id) # Check for NF status in a separate thread - gth = self.thread_pool.spawn(self._create_per_node_perf, - context, network_function_id) + gth = self.thread_pool.spawn(self._wait_for_network_function_operation_completion, + context, network_function_id, operation='create') self.active_threads.append(gth) - self.thread_list.append(th) # At last wait for the threads to complete, success/failure/timeout if len(self.active_threads) == self.sc_node_count: for gth in self.active_threads: gth.wait() + self.active_threads = [] def update(self, context): context._plugin_context = self._get_resource_owner_context( From 24f1be80731fd7c07dd310842266e4c46d9eebdd Mon Sep 17 00:00:00 2001 From: mak Date: Fri, 3 Jun 2016 16:53:12 +0530 Subject: [PATCH 09/17] corrected token related issues identified during atf testing --- .../ncp/node_drivers/nfp_node_driver.py | 4 ++- .../config_drivers/heat_driver.py | 31 ++++++------------- .../drivers/orchestration_driver.py | 4 +-- .../modules/device_orchestrator.py | 17 ++++++++-- .../modules/service_orchestrator.py | 5 ++- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py index f6136ca221..464d22e4aa 100644 --- a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py +++ b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py @@ -696,6 +696,7 @@ def _create_network_function(self, context): 'management': {'pt':<>, 'ptg':<>, 'port':<>, 'subnet':<>}, 'management_ptg_id': <>, 'network_function_mode': nfp_constants.GBP_MODE, + 'tenant_id': <> } """ @@ -765,7 +766,8 @@ def _create_network_function(self, context): 'consumer': consumer, 'management': management, 'management_ptg_id': sc_instance['management_ptg_id'], - 'network_function_mode': nfp_constants.GBP_MODE} + 'network_function_mode': nfp_constants.GBP_MODE, + 'tenant_id': context.provider['tenant_id']} return self.nfp_notifier.create_network_function( context.plugin_context, network_function=nfp_create_nf_data)['id'] diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index 6c6a98c3a3..56a1e50ec3 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -43,7 +43,6 @@ from gbpservice.nfp.core import log as nfp_logging -from gbpservice.nfp.core import context as nfp_core_context from gbpservice.nfp.core import threadpool as core_tp HEAT_DRIVER_OPTS = [ @@ -207,10 +206,7 @@ def keystone(self, user, pwd, tenant_name, tenant_id=None): return self.keystoneclient.get_scoped_keystone_token( user, pwd, tenant_name) - def _get_heat_client_v1(self, nfp_context, assign_admin=False): - tenant_id = nfp_context['resource_owner_context']['tenant_id'] - auth_token = nfp_context['resource_owner_context']['auth_token'] - + def _get_heat_client_v1(self, tenant_id, assign_admin=False): if assign_admin: try: self._assign_admin_user_to_project(tenant_id) @@ -221,6 +217,8 @@ def _get_heat_client_v1(self, nfp_context, assign_admin=False): user, password, tenant, auth_url =\ self.keystoneclient.get_keystone_creds() + auth_token = self.keystone(user, password, tenant, tenant_id=tenant_id) + timeout_mins, timeout_seconds = divmod(STACK_ACTION_WAIT_TIME, 60) if timeout_seconds: timeout_mins = timeout_mins + 1 @@ -1408,15 +1406,9 @@ def is_config_complete(self, stack_id, tenant_id, return failure_status def check_config_complete(self, nfp_context): + provider_tenant_id = nfp_context['tenant_id'] - provider = nfp_context['provider']['ptg'] - - token = nfp_context['resource_owner_context']['auth_token'] - tenant_id = nfp_context['resource_owner_context']['tenant_id'] - resource_owner_tenant_id = tenant_id - - heatclient = self._get_heat_client_v1(resource_owner_tenant_id, - tenant_id=provider['tenant_id']) + heatclient = self._get_heat_client_v1(provider_tenant_id) if not heatclient: return failure_status try: @@ -1584,18 +1576,15 @@ def apply_heat_config(self, nfp_context): provider_port = service_details['provider_port'] mgmt_ip = service_details['mgmt_ip'] - token = nfp_context['resource_owner_context']['auth_token'] - tenant_id = nfp_context['resource_owner_context']['tenant_id'] - resource_owner_tenant_id = tenant_id - - heatclient = self._get_heat_client_v1(resource_owner_tenant_id, - tenant_id=provider['tenant_id'], - assign_admin=True) + auth_token = nfp_context['resource_owner_context']['auth_token'] + provider_tenant_id = nfp_context['tenant_id'] + heatclient = self._get_heat_client_v1(provider_tenant_id, + assign_admin=True) if not heatclient: return None stack_template, stack_params = self._create_node_config_data( - token, tenant_id, + auth_token, provider_tenant_id, service_chain_node, service_chain_instance, provider, provider_port, consumer, consumer_port, network_function, mgmt_ip, service_details) diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index 6fdfefb6c9..52fc8e7ad1 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -28,9 +28,7 @@ from gbpservice.nfp.core import log as nfp_logging -from gbpservice.nfp.core import context as nfp_core_context - -from gbpservice.nfp.core import threadpool as core_tp +from gbpservice.nfp.core import task as core_task LOG = nfp_logging.getLogger(__name__) diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index e33bca3d53..09441c261f 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -32,7 +32,6 @@ import traceback from gbpservice.nfp.core import log as nfp_logging -from gbpservice.nfp.core import context as nfp_core_context LOG = nfp_logging.getLogger(__name__) @@ -452,7 +451,7 @@ def _decrement_device_ref_count(self, device): def _increment_device_interface_count(self, device): device['interfaces_in_use'] += len(device['ports']) - # self._update_network_function_device_db(device, device['status']) + self._update_network_function_device_db(device, device['status']) def _decrement_device_interface_count(self, device): device['interfaces_in_use'] -= len(device['ports']) @@ -675,6 +674,20 @@ def check_device_is_up(self, event): orchestration_driver.get_network_function_device_status(device)) if is_device_up == nfp_constants.ACTIVE: + # [(mak)TODO] - Update interfaces count here before + # sending health monitor rpc in DEVICE_UP event. + # [HACK] to handle a very corner case where + # PLUG_INTERFACES completes later than HEALTHMONITOR. + # till proper fix is identified. + provider = nfp_context['provider']['ptg'] + consumer = nfp_context['consumer']['ptg'] + network_function_device = nfp_context['network_function_device'] + + if provider: + network_function_device['interfaces_in_use'] += 1 + if consumer: + network_function_device['interfaces_in_use'] += 1 + # create event DEVICE_UP self._create_event(event_id='DEVICE_UP', event_data=nfp_context) diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 007c02fe49..16693d4fc5 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -620,11 +620,12 @@ def create_network_function(self, context, network_function_info): 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 = network_function_info['service_profile'] admin_token = network_function_info['resource_owner_context']['auth_token'] - tenant_id = network_function_info['resource_owner_context']['tenant_id'] 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'] @@ -843,8 +844,6 @@ def apply_user_config(self, event): request_data = event.data nfp_context = event.data['nfp_context'] - nfp_core_context.store_nfp_context(nfp_context) - network_function = nfp_context['network_function'] network_function_details = self.get_network_function_details( network_function['id']) From d3f62657df87f96cc1a630e7f53ab6123eaf46f8 Mon Sep 17 00:00:00 2001 From: mak Date: Fri, 3 Jun 2016 16:56:53 +0530 Subject: [PATCH 10/17] removed unused code --- gbpservice/nfp/configurator/agents/agent_base.py | 4 ---- gbpservice/nfp/configurator/agents/generic_config.py | 7 ------- 2 files changed, 11 deletions(-) diff --git a/gbpservice/nfp/configurator/agents/agent_base.py b/gbpservice/nfp/configurator/agents/agent_base.py index 7ce3768237..810b2d6a44 100644 --- a/gbpservice/nfp/configurator/agents/agent_base.py +++ b/gbpservice/nfp/configurator/agents/agent_base.py @@ -183,10 +183,6 @@ def process_batch(self, ev): result = getattr(driver, method)(context, resource_data) else: result = getattr(driver, method)(**resource_data) - ''' - # [AKASH] - result = const.SUCCESS - ''' success = True if result == 'SUCCESS' else False except Exception as err: result = ("Failed to process %s request. %s" % diff --git a/gbpservice/nfp/configurator/agents/generic_config.py b/gbpservice/nfp/configurator/agents/generic_config.py index 79ffc213c8..b27ee0cdeb 100644 --- a/gbpservice/nfp/configurator/agents/generic_config.py +++ b/gbpservice/nfp/configurator/agents/generic_config.py @@ -223,13 +223,6 @@ def handle_event(self, ev): return # Process HM poll events elif ev.id == gen_cfg_const.EVENT_CONFIGURE_HEALTHMONITOR: - ''' - # [AKASH] - result = common_const.SUCCESS - notification_data = self._prepare_notification_data(ev, result) - self.notify._notification(notification_data) - return - ''' resource_data = ev.data.get('resource_data') periodicity = resource_data.get('periodicity') if periodicity == gen_cfg_const.INITIAL: From eb2f863050da082e274f95bb0760d8f0e78f6708 Mon Sep 17 00:00:00 2001 From: mak Date: Fri, 3 Jun 2016 17:20:49 +0530 Subject: [PATCH 11/17] removed commented code --- .../nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py | 4 ---- gbpservice/nfp/lib/RestClientOverUnix.py | 2 -- 2 files changed, 6 deletions(-) diff --git a/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py b/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py index 78a88f05d3..6ac434df54 100644 --- a/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py +++ b/gbpservice/nfp/configurator/drivers/firewall/vyos/vyos_fw_driver.py @@ -564,10 +564,6 @@ def create_firewall(self, context, firewall, host): " %r. URL: %s" % (firewall['id'], firewall['tenant_id'], url)) LOG.info(msg) data = jsonutils.dumps(firewall) - ''' - # [AKASH] - return const.STATUS_ACTIVE - ''' try: resp = requests.post(url, data, timeout=self.timeout) except requests.exceptions.ConnectionError as err: diff --git a/gbpservice/nfp/lib/RestClientOverUnix.py b/gbpservice/nfp/lib/RestClientOverUnix.py index 9f526975cf..15a3729db2 100644 --- a/gbpservice/nfp/lib/RestClientOverUnix.py +++ b/gbpservice/nfp/lib/RestClientOverUnix.py @@ -82,8 +82,6 @@ def send_request(self, path, method_type, request_method='http', if method_type.upper() != 'GET': body = jsonutils.dumps(body) body = zlib.compress(body) - if body: - LOG.error("Compressed data for method %s : %s" %(method_type, len(body))) path = '/v1/nfp/' + path url = urlparse.urlunsplit(( request_method, From a8b4eddafba5f271576821474167cec59a506cab Mon Sep 17 00:00:00 2001 From: mak Date: Fri, 3 Jun 2016 18:56:50 +0530 Subject: [PATCH 12/17] corrected some more issues found during atf" --- .../drivers/orchestration_driver.py | 34 +++++++++++++------ .../modules/device_orchestrator.py | 3 +- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index 52fc8e7ad1..e8442cf3f9 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -918,16 +918,30 @@ def plug_network_function_device_interfaces(self, device_data, executor = core_task.TaskExecutor(jobs=10) for port in device_data['ports']: - service_type = device_data['service_details']['service_type'].lower() - if service_type == nfp_constants.FIREWALL.lower(): - executor.add_job('SET_PROMISCUOS_MODE', - network_handler.set_promiscuos_mode, - token, port['id']) - executor.add_job('ATTACH_INTERFACE', - self.compute_handler_nova.attach_interface, - token, tenant_id, device_data['id'], - port['id']) - + if port['port_classification'] == nfp_constants.PROVIDER: + service_type = device_data['service_details']['service_type'].lower() + if service_type == nfp_constants.FIREWALL.lower(): + executor.add_job('SET_PROMISCUOS_MODE', + network_handler.set_promiscuos_mode, + token, port['id']) + executor.add_job('ATTACH_INTERFACE', + self.compute_handler_nova.attach_interface, + token, tenant_id, device_data['id'], + port['id']) + break + + for port in device_data['ports']: + if port['port_classification'] == nfp_constants.CONSUMER: + service_type = device_data['service_details']['service_type'].lower() + if service_type == nfp_constants.FIREWALL.lower(): + executor.add_job('SET_PROMISCUOS_MODE', + network_handler.set_promiscuos_mode, + token, port['id']) + executor.add_job('ATTACH_INTERFACE', + self.compute_handler_nova.attach_interface, + token, tenant_id, device_data['id'], + port['id']) + break executor.fire() except Exception as e: diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index 09441c261f..2b16843f25 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -871,7 +871,8 @@ def plug_interfaces_v1(self, event): 'service_details': service_details, 'token': token, 'tenant_id': tenant_id, - 'interfaces_in_use': network_function_device['interfaces_in_use']} + 'interfaces_in_use': network_function_device['interfaces_in_use'], + 'status': network_function_device['status']} _ifaces_plugged_in, advance_sharing_ifaces = ( orchestration_driver.plug_network_function_device_interfaces( From 377e3d2ab33b7457346814fdd0140e3dc6c355df Mon Sep 17 00:00:00 2001 From: mak Date: Sat, 4 Jun 2016 01:05:56 +0530 Subject: [PATCH 13/17] fixed heat driver to use consuming ptg for a prs not the stitching ptg --- .../ncp/node_drivers/nfp_node_driver.py | 45 +++++++++++++++++-- .../config_drivers/heat_driver.py | 33 ++++++++++---- .../drivers/orchestration_driver.py | 4 +- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py index 464d22e4aa..ddc649831e 100644 --- a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py +++ b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py @@ -39,7 +39,7 @@ from gbpservice.nfp.common import constants as nfp_constants from gbpservice.nfp.common import topics as nfp_rpc_topics - +from gbpservice.neutron.services.grouppolicy.common import constants as gp_constants NFP_NODE_DRIVER_OPTS = [ cfg.BoolOpt('is_service_admin_owned', @@ -682,6 +682,36 @@ def _is_node_order_in_spec_supported(self, context): raise InvalidNodeOrderInChain( node_order=allowed_chain_combinations) + def _get_consumers_for_provider(self, context, provider): + ''' + { + consuming_ptgs_details: [{'ptg': <>, 'subnets': <>}] + consuming_eps_details: [] + } + ''' + + consuming_ptgs_details = [] + consuming_eps_details = [] + + provided_prs_id = provider['provided_policy_rule_sets'][0] + provided_prs = context.gbp_plugin.get_policy_rule_set( + context.plugin_context, provided_prs_id) + consuming_ptg_ids = provided_prs['consuming_policy_target_groups'] + consuming_ep_ids = provided_prs['consuming_external_policies'] + + consuming_ptgs = context.gbp_plugin.get_policy_target_groups( + context.plugin_context, filters={'id':consuming_ptg_ids}) + consuming_eps_details = context.gbp_plugin.get_external_policies( + context.plugin_context, filters={'id': consuming_ep_ids}) + + for ptg in consuming_ptgs: + subnet_ids = ptg['subnets'] + subnets = context.core_plugin.get_subnets(context.plugin_context, filters={'id':subnet_ids}) + consuming_ptgs_details.append({'ptg':ptg, 'subnets':subnets}) + + return consuming_ptgs_details, consuming_ep_details + + def _create_network_function(self, context): """ nfp_create_nf_data :- @@ -696,7 +726,9 @@ def _create_network_function(self, context): 'management': {'pt':<>, 'ptg':<>, 'port':<>, 'subnet':<>}, 'management_ptg_id': <>, 'network_function_mode': nfp_constants.GBP_MODE, - 'tenant_id': <> + 'tenant_id': <>, + 'consuming_ptgs_details': [], + 'consuming_eps_details': [] } """ @@ -704,6 +736,11 @@ def _create_network_function(self, context): sc_instance = context.instance service_targets = self._get_service_targets(context) + + consuming_ptgs_details, consuming_eps_details = \ + self._get_consumers_for_provider(context, + service_targets['provider_ptg'][0]) + if context.current_profile['service_type'] == pconst.LOADBALANCER: config_param_values = sc_instance.get('config_param_values', {}) if config_param_values: @@ -767,7 +804,9 @@ def _create_network_function(self, context): 'management': management, 'management_ptg_id': sc_instance['management_ptg_id'], 'network_function_mode': nfp_constants.GBP_MODE, - 'tenant_id': context.provider['tenant_id']} + 'tenant_id': context.provider['tenant_id'], + 'consuming_ptgs_details': consuming_ptgs_details, + 'consuming_eps_details': consuming_eps_details} return self.nfp_notifier.create_network_function( context.plugin_context, network_function=nfp_create_nf_data)['id'] diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index 56a1e50ec3..cb756e876a 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -485,12 +485,12 @@ def _get_all_heat_resource_keys(self, template_resource_dict, return resource_keys def _create_firewall_template(self, auth_token, service_details, stack_template): - consumer = service_details['consumer_ptg'] provider = service_details['provider_ptg'] + consuming_ptgs_details = service_details['consuming_ptgs_details'] consumer_eps = service_details['consuming_external_policies'] - if (consumer is None) and (consumer_eps is None): + if (not consuming_ptg_details) and (not consumer_eps): return None is_template_aws_version = stack_template.get( @@ -513,13 +513,29 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) fw_rule_keys=fw_rule_keys, fw_policy_key=fw_policy_key) - consumer_cidr = service_details['consumer_subnet']['cidr'] - self._append_firewall_rule(stack_template, provider_cidr, consumer_cidr, fw_template_properties, consumer['id']) + for consumer in consuming_ptgs_details: + ptg = consumer['ptg'] + subnets = consumer['subnets'] + + # Skip the stitching PTG + if ptg['proxied_group_id']: + continue + + fw_template_properties.update({'name': ptg['id'][:3]}) + for subnet in subnets: + if subnet['name'].startswith(APIC_OWNED_RES): + continue + + consumer_cidr = subnet['cidr'] + self._append_firewall_rule(stack_template, + provider_cidr, consumer_cidr, + fw_template_properties, ptg['id']) + for consumer_ep in consumer_eps: fw_template_properties.update({'name': consumer_ep[:3]}) self._append_firewall_rule(stack_template, provider_cidr, "0.0.0.0/0", fw_template_properties, - consumer_ep) + consumer_ep['id']) for rule_key in fw_rule_keys: del stack_template[resources_key][rule_key] @@ -1487,8 +1503,8 @@ def get_service_details_from_nfp_context(self, nfp_context): provider_subnet = nfp_context['provider']['subnet'] consumer_port = nfp_context['consumer']['port'] consumer_subnet = nfp_context['consumer']['subnet'] - _,consuming_eps = self._get_consumers_for_chain(token, provider_policy_target_group) - service_details['consuming_external_policies'] = consuming_eps + service_details['consuming_external_policies'] = nfp_context['consuming_ep_details'] + service_details['consuming_ptgs_details'] = nfp_context['consuming_ptgs_details'] return { 'service_profile': None, @@ -1503,7 +1519,8 @@ def get_service_details_from_nfp_context(self, nfp_context): 'heat_stack_id': heat_stack_id, 'provider_ptg': provider_policy_target_group, 'consumer_ptg': consumer_policy_target_group, - 'consuming_external_policies': service_details['consuming_external_policies'] + 'consuming_external_policies': service_details['consuming_external_policies'], + 'consuming_ptgs_details': service_details['consuming_ptgs_details'] } def apply_config(self, network_function_details): diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index e8442cf3f9..efe52bb614 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -928,7 +928,9 @@ def plug_network_function_device_interfaces(self, device_data, self.compute_handler_nova.attach_interface, token, tenant_id, device_data['id'], port['id']) - break + + # Configurator expects interface to attach in order + executor.fire() for port in device_data['ports']: if port['port_classification'] == nfp_constants.CONSUMER: From 6a729e21f93323c737f7782b9feb1fa0701de920 Mon Sep 17 00:00:00 2001 From: mak Date: Sat, 4 Jun 2016 15:48:49 +0530 Subject: [PATCH 14/17] fixed review comments --- .../ncp/node_drivers/nfp_node_driver.py | 2 +- .../config_drivers/heat_driver.py | 72 +++---------------- .../drivers/orchestration_driver.py | 11 +-- 3 files changed, 19 insertions(+), 66 deletions(-) diff --git a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py index ddc649831e..15422bc064 100644 --- a/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py +++ b/gbpservice/neutron/services/servicechain/plugins/ncp/node_drivers/nfp_node_driver.py @@ -709,7 +709,7 @@ def _get_consumers_for_provider(self, context, provider): subnets = context.core_plugin.get_subnets(context.plugin_context, filters={'id':subnet_ids}) consuming_ptgs_details.append({'ptg':ptg, 'subnets':subnets}) - return consuming_ptgs_details, consuming_ep_details + return consuming_ptgs_details, consuming_eps_details def _create_network_function(self, context): diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index cb756e876a..531b1866bc 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -138,7 +138,7 @@ def _resource_owner_tenant_id(self): def _get_resource_owner_context(self): if cfg.CONF.heat_driver.is_service_admin_owned: - tenant_id = None + tenant_id = self._resource_owner_tenant_id() user, pwd, tenant_name, auth_url =\ self.keystoneclient.get_keystone_creds() auth_token = self.keystoneclient.get_scoped_keystone_token( @@ -490,7 +490,7 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) consuming_ptgs_details = service_details['consuming_ptgs_details'] consumer_eps = service_details['consuming_external_policies'] - if (not consuming_ptg_details) and (not consumer_eps): + if (not consuming_ptgs_details) and (not consumer_eps): return None is_template_aws_version = stack_template.get( @@ -505,7 +505,8 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) stack_template['resources'], is_template_aws_version, 'OS::Neutron::FirewallPolicy')[0] - provider_cidr = service_details['provider_subnet']['cidr'] + provider_subnet = service_details['provider_subnet'] + provider_cidr = provider_subnet['cidr'] fw_template_properties = dict( resources_key=resources_key, properties_key=properties_key, @@ -532,7 +533,7 @@ def _create_firewall_template(self, auth_token, service_details, stack_template) fw_template_properties, ptg['id']) for consumer_ep in consumer_eps: - fw_template_properties.update({'name': consumer_ep[:3]}) + fw_template_properties.update({'name': consumer_ep['id'][:3]}) self._append_firewall_rule(stack_template, provider_cidr, "0.0.0.0/0", fw_template_properties, consumer_ep['id']) @@ -827,7 +828,7 @@ def _update_node_config(self, auth_token, tenant_id, service_profile, service_chain_node, service_chain_instance, provider, consumer_port, network_function, provider_port, update=False, mgmt_ip=None, - consumer=None, service_details=None): + consumer=None): nf_desc = None common_desc = {'network_function_id': network_function['id']} provider_cidr = provider_subnet = None @@ -1147,62 +1148,6 @@ def get_provider_consumer_details(self, gbp, admin_token, nfp_context, thread_po result['provider']['subnet'] = provider_subnet result['provider']['consuming_eps'] = consuming_external_policies - def get_service_details_from_cache(self, nfp_context, network_function_details): - network_function = network_function_details['network_function'] - network_function_instance = network_function_details.get('network_function_instance') - service_details = nfp_context['nfp_service_data']['service_details'] - if service_details['device_type'] != 'None': - network_function_device = network_function_details[ - 'network_function_device'] - mgmt_ip = network_function_device['mgmt_ip_address'] - else: - mgmt_ip = None - - admin_token = self.keystoneclient.get_admin_token() - heat_stack_id = network_function['heat_stack_id'] - service_id = network_function['service_id'] - service_chain_id = network_function['service_chain_id'] - - thread_pool = core_tp.ThreadPool() - - prov_cons_result={} - th3 = thread_pool.dispatch(self.get_provider_consumer_details, self.gbp_client, admin_token, nfp_context, thread_pool, prov_cons_result) - sc_node_result={} - th1 = thread_pool.dispatch(self.get_servicechain_node, self.gbp_client, admin_token, service_id, sc_node_result) - sc_instance_result={} - th2 = thread_pool.dispatch(self.get_servicechain_instance, self.gbp_client, admin_token, service_chain_id, sc_instance_result) - - th1.wait() - th2.wait() - th3.wait() - - servicechain_node = sc_node_result.get('result', None) - servicechain_instance = sc_instance_result.get('result', None) - consumer_policy_target_group = prov_cons_result['consumer']['ptg'] - provider_policy_target_group = prov_cons_result['provider']['ptg'] - provider_port = prov_cons_result['provider']['port'] - provider_subnet = prov_cons_result['provider']['subnet'] - consumer_port = prov_cons_result['consumer']['port'] - consumer_subnet = prov_cons_result['consumer']['subnet'] - - service_details['consuming_external_policies'] = prov_cons_result['provider']['consuming_eps'] - - return { - 'service_profile': None, - 'service_details': service_details, - 'servicechain_node': servicechain_node, - 'servicechain_instance': servicechain_instance, - 'consumer_port': consumer_port, - 'consumer_subnet': consumer_subnet, - 'provider_port': provider_port, - 'provider_subnet': provider_subnet, - 'mgmt_ip': mgmt_ip, - 'heat_stack_id': heat_stack_id, - 'provider_ptg': provider_policy_target_group, - 'consumer_ptg': consumer_policy_target_group, - 'consuming_external_policies': service_details['consuming_external_policies'] - } - def get_service_details(self, network_function_details): db_handler = nfp_db.NFPDbBase() @@ -1422,7 +1367,12 @@ def is_config_complete(self, stack_id, tenant_id, return failure_status def check_config_complete(self, nfp_context): + success_status = "COMPLETED" + failure_status = "ERROR" + intermediate_status = "IN_PROGRESS" + provider_tenant_id = nfp_context['tenant_id'] + stack_id = nfp_context['heat_stack_id'] heatclient = self._get_heat_client_v1(provider_tenant_id) if not heatclient: diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index efe52bb614..06cade83f9 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -54,7 +54,7 @@ class OrchestrationDriver(object): Launches the VM with all the management and data ports and a new VM is launched for each Network Service Instance """ - def __init__(self, config, supports_device_sharing=False, + def __init__(self, config, supports_device_sharing=True, supports_hotplug=True, max_interfaces=5): self.service_vendor = 'general' self.supports_device_sharing = supports_device_sharing @@ -454,9 +454,12 @@ def get_image_id(self, nova, token, admin_tenant_id, image_name): LOG.error("Get image id failed !!") - def create_instance(self, nova, token, admin_tenant_id, image_id, flavor, interfaces_to_attach, instance_name, result): + def create_instance(self, nova, token, admin_tenant_id, + image_id, flavor, interfaces_to_attach, + instance_name, result): try: - instance_id = nova.create_instance(token, admin_tenant_id, image_id, flavor, interfaces_to_attach, instance_name) + instance_id = nova.create_instance(token, admin_tenant_id, + image_id, flavor, interfaces_to_attach, instance_name) result['result'] = instance_id except Exception as e: LOG.error("Create instance failed !!!") @@ -928,7 +931,7 @@ def plug_network_function_device_interfaces(self, device_data, self.compute_handler_nova.attach_interface, token, tenant_id, device_data['id'], port['id']) - + break # Configurator expects interface to attach in order executor.fire() From fa8f7f0549073da279d2438faaa35d2148eb4346 Mon Sep 17 00:00:00 2001 From: mak Date: Sat, 4 Jun 2016 16:06:53 +0530 Subject: [PATCH 15/17] reverted back new argument introduced to get_heat_client" --- .../nfp/orchestrator/config_drivers/heat_driver.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index 531b1866bc..eb3140b73e 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -237,14 +237,13 @@ def _get_heat_client_v1(self, tenant_id, assign_admin=False): return heat_client - def _get_heat_client(self, resource_owner_tenant_id, tenant_id=None, assign_admin=False): + def _get_heat_client(self, resource_owner_tenant_id, tenant_id=None): user_tenant_id = tenant_id or resource_owner_tenant_id - if assign_admin: - try: - self._assign_admin_user_to_project(user_tenant_id) - except Exception: - LOG.exception(_LE("Failed to assign admin user to project")) - return None + try: + self._assign_admin_user_to_project(user_tenant_id) + except Exception: + LOG.exception(_LE("Failed to assign admin user to project")) + return None user, password, tenant, auth_url =\ self.keystoneclient.get_keystone_creds() From 06e66ec3167e4b569c8066f5412a1bd66e674acb Mon Sep 17 00:00:00 2001 From: mak Date: Sat, 4 Jun 2016 20:05:20 +0530 Subject: [PATCH 16/17] merged the code from running machine --- gbpservice/nfp/core/task.py | 17 +++--- .../config_drivers/heat_driver.py | 5 +- .../drivers/orchestration_driver.py | 52 ++++++++++--------- .../modules/device_orchestrator.py | 10 ++-- .../modules/service_orchestrator.py | 3 +- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/gbpservice/nfp/core/task.py b/gbpservice/nfp/core/task.py index c42ad34937..efaaab2661 100644 --- a/gbpservice/nfp/core/task.py +++ b/gbpservice/nfp/core/task.py @@ -19,9 +19,9 @@ class InUse(Exception): """ pass -def _check_in_use(f): +def check_in_use(f): def wrapped(self, *args, **kwargs): - if f.fired: + if self.fired: raise InUse("Executor in use") return f(self, *args, **kwargs) return wrapped @@ -38,11 +38,16 @@ def __init__(self, jobs=0): self.fired = False @check_in_use - def add_job(id, func, *args, **kwargs): + def add_job(self, id, func, *args, **kwargs): result_store = kwargs.pop('result_store', None) + job = { - 'id':id, 'method': func, 'args': args, - 'kwargs': kwargs, 'result_store':result_store } + 'id':id, 'method': func, 'args': args, + 'kwargs': kwargs} + + if result_store is not None: + job.update({'result_store': result_store}) + self.pipe_line.append(job) def _complete(self): @@ -60,7 +65,7 @@ def fire(self): result = job['thread'].wait() job.pop('thread') job['result'] = result - if job['result_store']: + if 'result_store' in job.keys(): job['result_store']['result'] = result done_jobs = self.pipe_line[:] diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index eb3140b73e..e40a7fcb3a 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -1439,7 +1439,6 @@ def get_service_details_from_nfp_context(self, nfp_context): network_function_instance = nfp_context['network_function_instance'] service_details = nfp_context['service_details'] mgmt_ip = nfp_context['management']['port']['ip_address'] - token = nfp_context['resource_owner_context']['auth_token'] heat_stack_id = network_function['heat_stack_id'] service_id = network_function['service_id'] service_chain_id = network_function['service_chain_id'] @@ -1452,7 +1451,7 @@ def get_service_details_from_nfp_context(self, nfp_context): provider_subnet = nfp_context['provider']['subnet'] consumer_port = nfp_context['consumer']['port'] consumer_subnet = nfp_context['consumer']['subnet'] - service_details['consuming_external_policies'] = nfp_context['consuming_ep_details'] + service_details['consuming_external_policies'] = nfp_context['consuming_eps_details'] service_details['consuming_ptgs_details'] = nfp_context['consuming_ptgs_details'] return { @@ -1542,7 +1541,7 @@ def apply_heat_config(self, nfp_context): provider_port = service_details['provider_port'] mgmt_ip = service_details['mgmt_ip'] - auth_token = nfp_context['resource_owner_context']['auth_token'] + auth_token = nfp_context['resource_owner_context']['admin_token'] provider_tenant_id = nfp_context['tenant_id'] heatclient = self._get_heat_client_v1(provider_tenant_id, assign_admin=True) diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index 06cade83f9..d600b8f95c 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -223,7 +223,8 @@ def _get_interfaces_for_device_create(self, token, admin_tenant_id, network_hand network_handler) device_data['interfaces'] = [mgmt_interface] except Exception as e: - LOG.error("Creating interfaces for device create failed !") + LOG.exception(_LE('Failed to get interfaces for device creation.' + 'Error: %(error)s'), {'error', e}) def _delete_interfaces(self, device_data, interfaces, network_handler=None): @@ -451,31 +452,38 @@ def get_image_id(self, nova, token, admin_tenant_id, image_name): image_id = nova.get_image_id(token, admin_tenant_id, image_name) return image_id except Exception as e: - LOG.error("Get image id failed !!") + LOG.error(_LE('Failed to get image id for device creation.' + ' image name: %(image_name)s. Error: %(error)s'), + {'image_name': image_name, 'error': e}) def create_instance(self, nova, token, admin_tenant_id, image_id, flavor, interfaces_to_attach, - instance_name, result): + instance_name): try: instance_id = nova.create_instance(token, admin_tenant_id, image_id, flavor, interfaces_to_attach, instance_name) - result['result'] = instance_id + return instance_id except Exception as e: - LOG.error("Create instance failed !!!") + LOG.error(_LE('Failed to create %(device_type)s instance.' + 'Error: %(error)s'), + {'device_type': ( + device_data['service_details']['device_type']), + 'error': e}) - def get_neutron_port_details(self, network_handler, token, port_id, result): + def get_neutron_port_details(self, network_handler, token, port_id): try: (mgmt_ip_address, mgmt_mac, mgmt_cidr, gateway_ip, mgmt_port, mgmt_subnet) = network_handler.get_neutron_port_details(token, port_id) - result['result'] = {'neutron_port': mgmt_port['port'], + result = {'neutron_port': mgmt_port['port'], 'neutron_subnet': mgmt_subnet['subnet'], 'ip_address': mgmt_ip_address, 'mac': mgmt_mac, 'cidr': mgmt_cidr, 'gateway_ip': gateway_ip} + return result except Exception as e: import sys import traceback @@ -484,7 +492,8 @@ def get_neutron_port_details(self, network_handler, token, port_id, result): exc_traceback) LOG.error(traceback.format_exception(exc_type, exc_value, exc_traceback)) - LOG.error("Failed to get neutron port details !!!") + LOG.error(_LE('Failed to get management port details. ' + 'Error: %(error)s'), {'error': e}) @_set_network_handler @@ -535,6 +544,10 @@ def create_network_function_device(self, device_data, raise exceptions.ComputePolicyNotSupported( compute_policy=device_data['service_details']['device_type']) + token = device_data['token'] + admin_tenant_id = device_data['admin_tenant_id'] + image_name = self._get_image_name(device_data) + executor = core_task.TaskExecutor(jobs=3) image_id_result = {} @@ -555,8 +568,7 @@ def create_network_function_device(self, device_data, interfaces = device_data.pop('interfaces', None) if not interfaces: - LOG.exception(_LE('Failed to get interfaces for device creation.' - 'Error: %(error)s'), {'error', e}) + LOG.exception(_LE('Failed to get interfaces for device creation.')) return None else: management_interface = interfaces[0] @@ -566,9 +578,7 @@ def create_network_function_device(self, device_data, image_id = image_id_result.get('result', None) if not image_id: self._increment_stats_counter('image_details_get_failures') - LOG.error(_LE('Failed to get image id for device creation.' - ' image name: %(image_name)s. Error: %(error)s'), - {'image_name': image_name, 'error': e}) + LOG.error(_LE('Failed to get image id for device creation.')) self._delete_interfaces(device_data, interfaces, network_handler=network_handler) self._decrement_stats_counter('management_interfaces', @@ -643,7 +653,7 @@ def create_network_function_device(self, device_data, executor.add_job('CREATE_INSTANCE', self.create_instance, self.compute_handler_nova, - token, admin_tenant_id, flavor, + token, admin_tenant_id, image_id, flavor, interfaces_to_attach, instance_name, result_store = instance_id_result) @@ -659,11 +669,7 @@ def create_network_function_device(self, device_data, instance_id = instance_id_result.get('result', None) if not instance_id: self._increment_stats_counter('instance_launch_failures') - LOG.error(_LE('Failed to create %(device_type)s instance.' - 'Error: %(error)s'), - {'device_type': ( - device_data['service_details']['device_type']), - 'error': e}) + LOG.error(_LE('Failed to create %(device_type)s instance.')) self._delete_interfaces(device_data, interfaces, network_handler=network_handler) self._decrement_stats_counter('management_interfaces', @@ -677,8 +683,7 @@ def create_network_function_device(self, device_data, if not mgmt_neutron_port_info: self._increment_stats_counter('port_details_get_failures') - LOG.error(_LE('Failed to get management port details. ' - 'Error: %(error)s'), {'error': e}) + LOG.error(_LE('Failed to get management port details. ')) try: self.compute_handler_nova.delete_instance( token, @@ -925,7 +930,7 @@ def plug_network_function_device_interfaces(self, device_data, service_type = device_data['service_details']['service_type'].lower() if service_type == nfp_constants.FIREWALL.lower(): executor.add_job('SET_PROMISCUOS_MODE', - network_handler.set_promiscuos_mode, + network_handler.set_promiscuos_mode_v1, token, port['id']) executor.add_job('ATTACH_INTERFACE', self.compute_handler_nova.attach_interface, @@ -940,7 +945,7 @@ def plug_network_function_device_interfaces(self, device_data, service_type = device_data['service_details']['service_type'].lower() if service_type == nfp_constants.FIREWALL.lower(): executor.add_job('SET_PROMISCUOS_MODE', - network_handler.set_promiscuos_mode, + network_handler.set_promiscuos_mode_v1, token, port['id']) executor.add_job('ATTACH_INTERFACE', self.compute_handler_nova.attach_interface, @@ -1276,7 +1281,6 @@ def get_network_function_device_config_info(self, device_data, if consumer_cidr else [provider_cidr]), 'destination_cidr': consumer_cidr, - 'provider_mac': provider_mac, 'gateway_ip': consumer_gateway_ip, 'provider_interface_index': 2 } diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index 2b16843f25..d9b0088326 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -525,7 +525,7 @@ def _prepare_device_data_from_nfp_context(self, nfp_context): network_function_instance = nfp_context['network_function_instance'] service_details = nfp_context['service_details'] - device_data['token'] = nfp_context['resource_owner_context']['auth_token'] + device_data['token'] = nfp_context['resource_owner_context']['admin_token'] device_data['admin_tenant_id'] = nfp_context['resource_owner_context']['admin_tenant_id'] device_data['name'] = network_function_instance['name'] device_data['share_existing_device'] = nfp_context['share_existing_device'] @@ -658,7 +658,7 @@ def check_device_is_up(self, event): service_details= nfp_context['service_details'] network_function_device = nfp_context['network_function_device'] - token = nfp_context['resource_owner_context']['auth_token'] + token = nfp_context['resource_owner_context']['admin_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] device = { @@ -847,8 +847,8 @@ def plug_interfaces_v1(self, event): service_details = nfp_context['service_details'] network_function_device = nfp_context['network_function_device'] - token = nfp_context['resource_owner_context']['auth_token'] - tenant_id = nfp_context['resource_owner_context']['tenant_id'] + token = nfp_context['resource_owner_context']['admin_token'] + tenant_id = nfp_context['resource_owner_context']['admin_tenant_id'] consumer = nfp_context['consumer'] provider = nfp_context['provider'] @@ -905,7 +905,7 @@ def create_device_configuration(self, event): nfp_context = event.data service_details = nfp_context['service_details'] - token = nfp_context['resource_owner_context']['auth_token'] + token = nfp_context['resource_owner_context']['admin_token'] tenant_id = nfp_context['resource_owner_context']['tenant_id'] consumer = nfp_context['consumer'] provider = nfp_context['provider'] diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 16693d4fc5..218000f904 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -71,7 +71,7 @@ def events_init(controller, config, service_orchestrator): 'DELETE_USER_CONFIG_IN_PROGRESS', 'CONFIG_APPLIED', 'USER_CONFIG_APPLIED', 'USER_CONFIG_DELETED', 'USER_CONFIG_DELETE_FAILED', 'USER_CONFIG_UPDATE_FAILED', - 'USER_CONFIG_FAILED'] + 'USER_CONFIG_FAILED', 'CHECK_USER_CONFIG_COMPLETE'] events_to_register = [] for event in events: events_to_register.append( @@ -625,7 +625,6 @@ def create_network_function(self, context, network_function_info): # GBP or Neutron mode = network_function_info['network_function_mode'] service_profile = network_function_info['service_profile'] - admin_token = network_function_info['resource_owner_context']['auth_token'] 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'] From ea0fa4bccc42e4416fd17683540dd8ccc3b6d432 Mon Sep 17 00:00:00 2001 From: AkashDeep Date: Mon, 6 Jun 2016 21:20:36 +0530 Subject: [PATCH 17/17] changes while paralel execution in demo setup --- .../coal/networking/nfp_gbp_network_driver.py | 16 ++++++++-------- .../networking/nfp_neutron_network_driver.py | 19 ++++++++++--------- .../config_drivers/heat_client.py | 2 +- .../config_drivers/heat_driver.py | 6 +++--- .../drivers/orchestration_driver.py | 3 ++- .../modules/device_orchestrator.py | 4 ++-- .../modules/service_orchestrator.py | 4 ++-- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py index e0a257a9b3..0cfb91756b 100644 --- a/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py +++ b/gbpservice/nfp/orchestrator/coal/networking/nfp_gbp_network_driver.py @@ -42,18 +42,18 @@ def update_port(self, token, port_id, port): return pt['port_id'] def get_neutron_port_details(self, token, port_id): - self.network_handler = openstack_driver.NeutronClient(self.config) + #self.network_handler = openstack_driver.NeutronClient(self.config) port_details = super(NFPGBPNetworkDriver, self).get_port_and_subnet_details( token, port_id) - self.network_handler = openstack_driver.GBPClient(self.config) + #self.network_handler = openstack_driver.GBPClient(self.config) return port_details def get_port_details(self, token, port_id): _port_id = self.get_port_id(token, port_id) - self.network_handler = openstack_driver.NeutronClient(self.config) + #self.network_handler = openstack_driver.NeutronClient(self.config) port_details = super(NFPGBPNetworkDriver, self).get_port_details( token, _port_id) - self.network_handler = openstack_driver.GBPClient(self.config) + #self.network_handler = openstack_driver.GBPClient(self.config) return port_details def get_networks(self, token, filters): @@ -62,11 +62,11 @@ def get_networks(self, token, filters): def set_promiscuos_mode(self, token, port_id): port_id = self.get_port_id(token, port_id) - self.network_handler = openstack_driver.NeutronClient(self.config) + #self.network_handler = openstack_driver.NeutronClient(self.config) super(NFPGBPNetworkDriver, self).set_promiscuos_mode(token, port_id) - self.network_handler = openstack_driver.GBPClient(self.config) + #self.network_handler = openstack_driver.GBPClient(self.config) def set_promiscuos_mode_v1(self, token, port_id): - self.network_handler = openstack_driver.NeutronClient(self.config) + #self.network_handler = openstack_driver.NeutronClient(self.config) super(NFPGBPNetworkDriver, self).set_promiscuos_mode(token, port_id) - self.network_handler = openstack_driver.GBPClient(self.config) + #self.network_handler = openstack_driver.GBPClient(self.config) diff --git a/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py b/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py index e9f59e6805..10c871dd8e 100644 --- a/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py +++ b/gbpservice/nfp/orchestrator/coal/networking/nfp_neutron_network_driver.py @@ -18,28 +18,29 @@ class NFPNeutronNetworkDriver(ndb.NFPNetworkDriverBase): def __init__(self, config): - self.network_handler = openstack_driver.NeutronClient(config) + # self.network_handler = openstack_driver.NeutronClient(config) + self.neutron_client = openstack_driver.NeutronClient(config) def setup_traffic_steering(self): pass def create_port(self, token, tenant_id, net_id, name=None): - port = self.network_handler.create_port(token, tenant_id, net_id, + port = self.neutron_client.create_port(token, tenant_id, net_id, attrs={'name': name}) return port def delete_port(self, token, port_id): - self.network_handler.delete_port(token, port_id) + self.neutron_client.delete_port(token, port_id) def get_port_id(self, token, port_id): return port_id def update_port(self, token, port_id, port): - port = self.network_handler.update_port(token, port_id, port) + port = self.neutron_client.update_port(token, port_id, port) return port['port'] def get_port_and_subnet_details(self, token, port_id): - port = self.network_handler.get_port(token, port_id) + port = self.neutron_client.get_port(token, port_id) # ip ip = port['port']['fixed_ips'][0]['ip_address'] @@ -49,14 +50,14 @@ def get_port_and_subnet_details(self, token, port_id): # gateway ip subnet_id = port['port']['fixed_ips'][0]['subnet_id'] - subnet = self.network_handler.get_subnet(token, subnet_id) + subnet = self.neutron_client.get_subnet(token, subnet_id) cidr = subnet['subnet']['cidr'] gateway_ip = subnet['subnet']['gateway_ip'] return (ip, mac, cidr, gateway_ip, port, subnet) def get_port_details(self, token, port_id): - port = self.network_handler.get_port(token, port_id) + port = self.neutron_client.get_port(token, port_id) # ip ip = port['port']['fixed_ips'][0]['ip_address'] @@ -66,13 +67,13 @@ def get_port_details(self, token, port_id): # gateway ip subnet_id = port['port']['fixed_ips'][0]['subnet_id'] - subnet = self.network_handler.get_subnet(token, subnet_id) + subnet = self.neutron_client.get_subnet(token, subnet_id) cidr = subnet['subnet']['cidr'] gateway_ip = subnet['subnet']['gateway_ip'] return (ip, mac, cidr, gateway_ip) def set_promiscuos_mode(self, token, port_id): - self.network_handler.update_port(token, port_id, + self.neutron_client.update_port(token, port_id, security_groups=[], port_security_enabled=False) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_client.py b/gbpservice/nfp/orchestrator/config_drivers/heat_client.py index b0b241d75c..f243197c8e 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_client.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_client.py @@ -13,7 +13,7 @@ # under the License. from heatclient import client as heat_client from heatclient import exc as heat_exc -from neutron._i18n import _LW +from neutron.i18n import _LW from gbpservice.nfp.core import log as nfp_logging LOG = nfp_logging.getLogger(__name__) diff --git a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py index e40a7fcb3a..c6548c70db 100644 --- a/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py +++ b/gbpservice/nfp/orchestrator/config_drivers/heat_driver.py @@ -32,9 +32,9 @@ from heatclient import exc as heat_exc from keystoneclient import exceptions as k_exceptions -from neutron._i18n import _LE -from neutron._i18n import _LI -from neutron._i18n import _LW +from neutron.i18n import _LE +from neutron.i18n import _LI +from neutron.i18n import _LW from neutron.plugins.common import constants as pconst from oslo_config import cfg from oslo_serialization import jsonutils diff --git a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py index d600b8f95c..b3bcbc369d 100644 --- a/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py +++ b/gbpservice/nfp/orchestrator/drivers/orchestration_driver.py @@ -1,4 +1,5 @@ # 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 # @@ -938,7 +939,7 @@ def plug_network_function_device_interfaces(self, device_data, port['id']) break # Configurator expects interface to attach in order - executor.fire() + # executor.fire() for port in device_data['ports']: if port['port_classification'] == nfp_constants.CONSUMER: diff --git a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py index d9b0088326..0a25622a11 100644 --- a/gbpservice/nfp/orchestrator/modules/device_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/device_orchestrator.py @@ -10,8 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron._i18n import _LE -from neutron._i18n import _LI +from neutron.i18n import _LE +from neutron.i18n import _LI import oslo_messaging as messaging from gbpservice.nfp.common import constants as nfp_constants diff --git a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py index 218000f904..1f17ede2a2 100644 --- a/gbpservice/nfp/orchestrator/modules/service_orchestrator.py +++ b/gbpservice/nfp/orchestrator/modules/service_orchestrator.py @@ -10,8 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron._i18n import _LE -from neutron._i18n import _LI +from neutron.i18n import _LE +from neutron.i18n import _LI from neutron.common import rpc as n_rpc from neutron import context as n_context from oslo_log import helpers as log_helpers