From 18de74656c52be9a1c14d30eb14d19aa7ce858f4 Mon Sep 17 00:00:00 2001 From: Chamarty Date: Wed, 5 Apr 2017 10:13:09 -0400 Subject: [PATCH] CAL and SDNAL cleanup for failure cases in accounts Change-Id: Icf7e139608e04f26c0c04f636916d0a775061c8e Signed-off-by: Chamarty --- .../rift/rwcal/openstack/openstack_drv.py | 43 ++++++--- .../vala/rwcal_openstack/rwcal_openstack.py | 52 +++-------- .../tasklets/rwnsmtasklet/rwnsmtasklet.py | 2 +- .../vala/rwsdn_openstack/rwsdn_openstack.py | 90 ++++++++++++------- 4 files changed, 98 insertions(+), 89 deletions(-) diff --git a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py index 6ee2cb6d..d6831a73 100644 --- a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py +++ b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py @@ -29,6 +29,7 @@ from . import utils as drv_utils # Exceptions import keystoneclient.exceptions as KeystoneExceptions +import neutronclient.common.exceptions as NeutronException class ValidationError(Exception): @@ -137,7 +138,7 @@ class OpenstackDriver(object): self.cinder_drv = ci_drv.CinderDriver(self.sess_drv, region_name = region, logger = self.log) - except Exception as e: + except Exception: self.cinder_drv = None self.ceilo_drv = ce_drv.CeilometerDriver(self.sess_drv, @@ -171,7 +172,10 @@ class OpenstackDriver(object): return self._cache['cinder'] def build_resource_cache(self): - self.build_network_resource_cache() + try: + self.build_network_resource_cache() + except KeyError: + raise self.build_nova_resource_cache() self.build_cinder_resource_cache() self.build_glance_resource_cache() @@ -215,11 +219,13 @@ class OpenstackDriver(object): self.log.info("Discovering management network %s", self._mgmt_network) network_list = self._cache_populate(self.neutron_drv.network_get, None, - **{'network_name':self._mgmt_network}) + **{'network_name': self._mgmt_network}) if network_list: self.neutron_cache['mgmt_net'] = network_list['id'] else: - raise KeyError("Error") + msg = "Could not find management network %s" % self._mgmt_network + self.log.error(msg) + raise KeyError(msg) def _build_glance_image_list(self): @@ -231,7 +237,6 @@ class OpenstackDriver(object): def _build_cinder_volume_list(self): self.log.info("Discovering volumes") - vollist = self.cinder_volume_list() self.cinder_cache['volumes'] = self._cache_populate(self.cinder_volume_list, list()) return self.cinder_cache['volumes'] @@ -244,7 +249,10 @@ class OpenstackDriver(object): def build_network_resource_cache(self): self.log.info("Building network resource cache") - self._get_neutron_mgmt_network() + try: + self._get_neutron_mgmt_network() + except KeyError: + raise self._build_neutron_security_group_list() self._build_neutron_subnet_prefix_list() @@ -316,22 +324,28 @@ class OpenstackDriver(object): self.sess_drv.invalidate_auth_token() self.sess_drv.auth_token self.build_resource_cache() + except KeystoneExceptions.Unauthorized as e: + self.log.error("Invalid credentials ") + raise ValidationError("Invalid Credentials: "+ str(e)) except KeystoneExceptions.AuthorizationFailure as e: self.log.error("Unable to authenticate or validate the existing credentials. Exception: %s", str(e)) raise ValidationError("Invalid Credentials: "+ str(e)) + except NeutronException.NotFound as e: + self.log.error("Given management network could not be found for Openstack account ") + raise ValidationError("Neutron network not found "+ str(e)) except Exception as e: self.log.error("Could not connect to Openstack. Exception: %s", str(e)) raise ValidationError("Connection Error: "+ str(e)) - + def glance_image_create(self, **kwargs): - if not 'disk_format' in kwargs: + if 'disk_format' not in kwargs: kwargs['disk_format'] = 'qcow2' - if not 'container_format' in kwargs: + if 'container_format' not in kwargs: kwargs['container_format'] = 'bare' - if not 'min_disk' in kwargs: + if 'min_disk' not in kwargs: kwargs['min_disk'] = 0 - if not 'min_ram' in kwargs: + if 'min_ram' not in kwargs: kwargs['min_ram'] = 0 return self.glance_drv.image_create(**kwargs) @@ -374,7 +388,7 @@ class OpenstackDriver(object): def nova_server_create(self, **kwargs): if 'security_groups' not in kwargs: - kwargs['security_groups'] = [ s['name'] for s in self._nova_security_groups ] + kwargs['security_groups'] = [s['name'] for s in self._nova_security_groups] return self.nova_drv.server_create(**kwargs) def nova_server_add_port(self, server_id, port_id): @@ -428,6 +442,9 @@ class OpenstackDriver(object): def nova_volume_list(self, server_id): return self.nova_drv.volume_list(server_id) + def neutron_extensions_list(self): + return self.neutron_drv.extensions_list() + def neutron_network_list(self): return self.neutron_drv.network_list() @@ -592,7 +609,7 @@ class OpenstackDriver(object): def cinder_volume_list(self): return self.cinder_drv.volume_list() - def cinder_volume_get(self,vol_id): + def cinder_volume_get(self, vol_id): return self.cinder_drv.volume_get(vol_id) def cinder_volume_set_metadata(self, volumeid, metadata): diff --git a/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py b/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py index eac0d6c9..68702bbb 100644 --- a/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py +++ b/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py @@ -15,7 +15,6 @@ # limitations under the License. # -import contextlib import logging import os import subprocess @@ -32,8 +31,6 @@ import rift.rwcal.openstack as openstack_drv import rw_status import rift.cal.rwcal_status as rwcal_status import rwlogger -import neutronclient.common.exceptions as NeutronException -import keystoneclient.exceptions as KeystoneExceptions from gi.repository import ( @@ -44,9 +41,9 @@ from gi.repository import ( PREPARE_VM_CMD = "prepare_vm.py --auth_url {auth_url} --username {username} --password {password} --tenant_name {tenant_name} --region {region} --user_domain {user_domain} --project_domain {project_domain} --mgmt_network {mgmt_network} --server_id {server_id} --port_metadata " -rwstatus_exception_map = { IndexError: RwTypes.RwStatus.NOTFOUND, - KeyError: RwTypes.RwStatus.NOTFOUND, - NotImplementedError: RwTypes.RwStatus.NOT_IMPLEMENTED,} +rwstatus_exception_map = {IndexError: RwTypes.RwStatus.NOTFOUND, + KeyError: RwTypes.RwStatus.NOTFOUND, + NotImplementedError: RwTypes.RwStatus.NOT_IMPLEMENTED, } rwstatus = rw_status.rwstatus_from_exc_map(rwstatus_exception_map) rwcalstatus = rwcal_status.rwcalstatus_from_exc_map(rwstatus_exception_map) @@ -75,9 +72,6 @@ class RwcalAccountDriver(object): self.log = logger try: self._driver = openstack_drv.OpenstackDriver(logger = self.log, **kwargs) - except (KeystoneExceptions.Unauthorized, KeystoneExceptions.AuthorizationFailure, - NeutronException.NotFound) as e: - raise except Exception as e: self.log.error("RwcalOpenstackPlugin: OpenstackDriver init failed. Exception: %s" %(str(e))) raise @@ -154,34 +148,11 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): Validation Code and Details String """ status = RwcalYang.CloudConnectionStatus() - drv = self._use_driver(account) try: + drv = self._use_driver(account) drv.validate_account_creds() - except KeystoneExceptions.Unauthorized as e: - self.log.error("Invalid credentials given for VIM account %s", account.name) - status.status = "failure" - status.details = "Invalid Credentials: %s" % str(e) - - except KeystoneExceptions.AuthorizationFailure as e: - self.log.error("Bad authentication URL given for VIM account %s. Given auth url: %s", - account.name, account.openstack.auth_url) - status.status = "failure" - status.details = "Invalid auth url: %s" % str(e) - - except NeutronException.NotFound as e: - self.log.error("Given management network %s could not be found for VIM account %s", - account.openstack.mgmt_network, - account.name) - status.status = "failure" - status.details = "mgmt network does not exist: %s" % str(e) - - except openstack_drv.ValidationError as e: - self.log.error("RwcalOpenstackPlugin: OpenstackDriver credential validation failed. Exception: %s", str(e)) - status.status = "failure" - status.details = "Invalid Credentials: %s" % str(e) - except Exception as e: - msg = "RwcalOpenstackPlugin: OpenstackDriver connection failed. Exception: %s" %(str(e)) + msg = "RwcalOpenstackPlugin: Exception: %s" %(str(e)) self.log.error(msg) status.status = "failure" status.details = msg @@ -400,11 +371,8 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): kwargs['image_id'] = vminfo.image_id ### If floating_ip is required and we don't have one, better fail before any further allocation - pool_name = None floating_ip = False if vminfo.has_field('allocate_public_address') and vminfo.allocate_public_address: - if account.openstack.has_field('floating_ip_pool'): - pool_name = account.openstack.floating_ip_pool floating_ip = True if vminfo.has_field('cloud_init') and vminfo.cloud_init.has_field('userdata'): @@ -441,7 +409,7 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): kwargs['availability_zone'] = None if vminfo.has_field('server_group'): - kwargs['scheduler_hints'] = {'group': vminfo.server_group } + kwargs['scheduler_hints'] = {'group': vminfo.server_group} else: kwargs['scheduler_hints'] = None @@ -540,10 +508,10 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): if key in vm.user_tags.fields: setattr(vm.user_tags, key, value) if 'OS-EXT-SRV-ATTR:host' in vm_info: - if vm_info['OS-EXT-SRV-ATTR:host'] != None: + if vm_info['OS-EXT-SRV-ATTR:host'] is not None: vm.host_name = vm_info['OS-EXT-SRV-ATTR:host'] if 'OS-EXT-AZ:availability_zone' in vm_info: - if vm_info['OS-EXT-AZ:availability_zone'] != None: + if vm_info['OS-EXT-AZ:availability_zone'] is not None: vm.availability_zone = vm_info['OS-EXT-AZ:availability_zone'] return vm @@ -680,7 +648,7 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): network = RwcalYang.NetworkInfoItem() network.network_name = network_info['name'] network.network_id = network_info['id'] - if ('provider:network_type' in network_info) and (network_info['provider:network_type'] != None): + if ('provider:network_type' in network_info) and (network_info['provider:network_type'] is not None): network.provider_network.overlay_type = network_info['provider:network_type'].upper() if ('provider:segmentation_id' in network_info) and (network_info['provider:segmentation_id']): network.provider_network.segmentation_id = network_info['provider:segmentation_id'] @@ -1068,7 +1036,7 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): cmd += (" --vol_metadata {}").format(tmp_file.name) exec_path = 'python3 ' + os.path.dirname(openstack_drv.__file__) - exec_cmd = exec_path+'/'+cmd + exec_cmd = exec_path + '/' + cmd self.log.info("Running command: %s" %(exec_cmd)) subprocess.call(exec_cmd, shell=True) diff --git a/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py b/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py index 99cb3f7b..69fac685 100755 --- a/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py +++ b/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py @@ -2011,7 +2011,7 @@ class NetworkServiceRecord(object): (member_vnfd.member_vnf_index_ref == const_vnfd.member_vnf_index): group_info = self.resolve_placement_group_cloud_construct(group) if group_info is None: - self._log.error("Could not resolve cloud-construct for placement group: %s", group.name) + self._log.info("Could not resolve cloud-construct for placement group: %s", group.name) ### raise PlacementGroupError("Could not resolve cloud-construct for placement group: {}".format(group.name)) else: self._log.info("Successfully resolved cloud construct for placement group: %s for VNF: %s (Member Index: %s)", diff --git a/rwlaunchpad/plugins/rwvns/vala/rwsdn_openstack/rwsdn_openstack.py b/rwlaunchpad/plugins/rwvns/vala/rwsdn_openstack/rwsdn_openstack.py index 6adece4e..a9ff983f 100644 --- a/rwlaunchpad/plugins/rwvns/vala/rwsdn_openstack/rwsdn_openstack.py +++ b/rwlaunchpad/plugins/rwvns/vala/rwsdn_openstack/rwsdn_openstack.py @@ -15,14 +15,12 @@ # limitations under the License. # -import contextlib import logging import gi gi.require_version('RwSdn', '1.0') -gi.require_version('RwCal', '1.0') -gi.require_version('RwcalYang', '1.0') +import rift.rwcal.openstack as openstack_drv from rift.rwcal.openstack import session as sess_drv from rift.rwcal.openstack import keystone as ks_drv from rift.rwcal.openstack import neutron as nt_drv @@ -39,15 +37,13 @@ import keystoneclient.exceptions as KeystoneExceptions from gi.repository import ( GObject, - RwCal, - RwSdn, # Vala package + RwSdn, # Vala package RwsdnalYang, - RwTypes, - RwcalYang) + RwTypes) -rwstatus_exception_map = { IndexError: RwTypes.RwStatus.NOTFOUND, +rwstatus_exception_map = {IndexError: RwTypes.RwStatus.NOTFOUND, KeyError: RwTypes.RwStatus.NOTFOUND, - NotImplementedError: RwTypes.RwStatus.NOT_IMPLEMENTED,} + NotImplementedError: RwTypes.RwStatus.NOT_IMPLEMENTED, } rwstatus = rw_status.rwstatus_from_exc_map(rwstatus_exception_map) rwcalstatus = rwcal_status.rwcalstatus_from_exc_map(rwstatus_exception_map) @@ -94,6 +90,7 @@ class OpenstackL2PortChainingDriver(object): project_domain_name = kwargs['project_domain'] if 'project_domain' in kwargs else None, user_domain_name = kwargs['user_domain'] if 'user_domain' in kwargs else None,) + self.auth_url = kwargs['auth_url'] cert_validate = kwargs['cert_validate'] if 'cert_validate' in kwargs else False region = kwargs['region_name'] if 'region_name' in kwargs else False @@ -115,17 +112,43 @@ class OpenstackL2PortChainingDriver(object): logger = self.log) def validate_account_creds(self): + status = RwsdnalYang.SdnConnectionStatus() try: self.sess_drv.invalidate_auth_token() self.sess_drv.auth_token + except KeystoneExceptions.Unauthorized as e: + self.log.error("Invalid credentials given for SDN account ") + status.status = "failure" + status.details = "Invalid Credentials: %s" % str(e) + except KeystoneExceptions.AuthorizationFailure as e: - self.log.error("Unable to authenticate or validate the existing credentials. Exception: %s", str(e)) - raise ValidationError("Invalid Credentials: "+ str(e)) + self.log.error("Bad authentication URL given for SDN account. Given auth url: %s", + self.auth_url) + status.status = "failure" + status.details = "Invalid auth url: %s" % str(e) + + except NeutronException.NotFound as e: + status.status = "failure" + status.details = "Neutron exception %s" % str(e) + + except openstack_drv.ValidationError as e: + self.log.error("RwcalOpenstackPlugin: OpenstackDriver credential validation failed. Exception: %s", str(e)) + status.status = "failure" + status.details = "Invalid Credentials: %s" % str(e) + except Exception as e: - self.log.error("Could not connect to Openstack. Exception: %s", str(e)) - raise ValidationError("Connection Error: "+ str(e)) + msg = "RwsdnOpenstackPlugin: OpenstackDriver connection failed. Exception: %s" %(str(e)) + self.log.error(msg) + status.status = "failure" + status.details = msg + + else: + status.status = "success" + status.details = "Connection was successful" + + return status - def delete_port_chain(self,port_chain_id): + def delete_port_chain(self, port_chain_id): "Delete port chain" try: result = self.portchain_drv.get_port_chain(port_chain_id) @@ -144,15 +167,15 @@ class OpenstackL2PortChainingDriver(object): port_pairs.extend(port_pair_group["port_pair_group"]["port_pairs"]) self.portchain_drv.delete_port_pair_group(port_pair_group_id) - self.log.debug("Port pairs during delete is %s",port_pairs) + self.log.debug("Port pairs during delete is %s", port_pairs) for port_pair_id in port_pairs: self.portchain_drv.delete_port_pair(port_pair_id) pass except Exception as e: - self.log.error("Error while delete port chain with id %s, exception %s", port_chain_id,str(e)) + self.log.error("Error while delete port chain with id %s, exception %s", port_chain_id, str(e)) - def update_port_chain(self,port_chain_id,flow_classifier_list): + def update_port_chain(self, port_chain_id, flow_classifier_list): result = self.portchain_drv.get_port_chain(port_chain_id) result.raise_for_status() port_chain = result.json()['port_chain'] @@ -160,20 +183,20 @@ class OpenstackL2PortChainingDriver(object): if port_chain and port_chain['flow_classifiers']: new_flow_classifier_list.extend(port_chain['flow_classifiers']) new_flow_classifier_list.extend(flow_classifier_list) - port_chain_id = self.portchain_drv.update_port_chain(port_chain['id'],flow_classifiers=new_flow_classifier_list) + port_chain_id = self.portchain_drv.update_port_chain(port_chain['id'], flow_classifiers=new_flow_classifier_list) return port_chain_id - def create_flow_classifer(self,classifier_name,classifier_dict): + def create_flow_classifer(self, classifier_name, classifier_dict): "Create flow classifier" - flow_classifier_id = self.portchain_drv.create_flow_classifier(classifier_name,classifier_dict) + flow_classifier_id = self.portchain_drv.create_flow_classifier(classifier_name, classifier_dict) return flow_classifier_id - def delete_flow_classifier(self,classifier_id): + def delete_flow_classifier(self, classifier_id): "Create flow classifier" try: self.portchain_drv.delete_flow_classifier(classifier_id) except Exception as e: - self.log.error("Error while deleting flow classifier with id %s, exception %s", classifier_id,str(e)) + self.log.error("Error while deleting flow classifier with id %s, exception %s", classifier_id, str(e)) def get_port_chain_list(self): result = self.portchain_drv.get_port_chain_list() @@ -204,6 +227,7 @@ class RwsdnAccountDriver(object): class SdnOpenstackPlugin(GObject.Object, RwSdn.Topology): instance_num = 1 + def __init__(self): GObject.Object.__init__(self) self.log = logging.getLogger('rwsdn.openstack.%s' % SdnOpenstackPlugin.instance_num) @@ -256,8 +280,8 @@ class SdnOpenstackPlugin(GObject.Object, RwSdn.Topology): Validation Code and Details String """ status = RwsdnalYang.SdnConnectionStatus() - drv = self._use_driver(account) try: + drv = self._use_driver(account) drv.validate_account_creds() except openstack_drv.ValidationError as e: @@ -278,14 +302,14 @@ class SdnOpenstackPlugin(GObject.Object, RwSdn.Topology): return status @rwstatus(ret_on_failure=[""]) - def do_create_vnffg_chain(self, account,vnffg): + def do_create_vnffg_chain(self, account, vnffg): """ Creates Service Function chain in ODL @param account - a SDN account """ - self.log.debug('Received Create VNFFG chain for account {}, chain {}'.format(account,vnffg)) + self.log.debug('Received Create VNFFG chain for account {}, chain {}'.format(account, vnffg)) drv = self._use_driver(account) port_list = list() vnf_chain_list = sorted(vnffg.vnf_chain_path, key = lambda x: x.order) @@ -293,16 +317,16 @@ class SdnOpenstackPlugin(GObject.Object, RwSdn.Topology): for path in vnf_chain_list: if prev_vm_id and path.vnfr_ids[0].vdu_list[0].vm_id == prev_vm_id: prev_entry = port_list.pop() - port_list.append((prev_entry[0],path.vnfr_ids[0].vdu_list[0].port_id)) + port_list.append((prev_entry[0], path.vnfr_ids[0].vdu_list[0].port_id)) prev_vm_id = None else: prev_vm_id = path.vnfr_ids[0].vdu_list[0].vm_id - port_list.append((path.vnfr_ids[0].vdu_list[0].port_id,path.vnfr_ids[0].vdu_list[0].port_id)) - vnffg_id = drv.create_port_chain(vnffg.name,port_list) + port_list.append((path.vnfr_ids[0].vdu_list[0].port_id, path.vnfr_ids[0].vdu_list[0].port_id)) + vnffg_id = drv.create_port_chain(vnffg.name, port_list) return vnffg_id @rwstatus - def do_terminate_vnffg_chain(self, account,vnffg_id): + def do_terminate_vnffg_chain(self, account, vnffg_id): """ Terminate Service Function chain in ODL @@ -319,8 +343,8 @@ class SdnOpenstackPlugin(GObject.Object, RwSdn.Topology): @param account - a SDN account """ - self.log.debug('Received Create VNFFG classifier for account {}, classifier {}'.format(account,vnffg_classifier)) - protocol_map = {1:'ICMP',6:'TCP',17:'UDP'} + self.log.debug('Received Create VNFFG classifier for account {}, classifier {}'.format(account, vnffg_classifier)) + protocol_map = {1: 'ICMP', 6: 'TCP', 17: 'UDP'} flow_classifier_list = list() drv = self._use_driver(account) for rule in vnffg_classifier.match_attributes: @@ -328,7 +352,7 @@ class SdnOpenstackPlugin(GObject.Object, RwSdn.Topology): flow_dict = {} for field, value in rule.as_dict().items(): if field == 'ip_proto': - flow_dict['protocol'] = protocol_map.get(value,None) + flow_dict['protocol'] = protocol_map.get(value, None) elif field == 'source_ip_address': flow_dict['source_ip_prefix'] = value elif field == 'destination_ip_address': @@ -343,7 +367,7 @@ class SdnOpenstackPlugin(GObject.Object, RwSdn.Topology): flow_dict['logical_source_port'] = vnffg_classifier.port_id flow_classifier_id = drv.create_flow_classifer(classifier_name, flow_dict) flow_classifier_list.append(flow_classifier_id) - drv.update_port_chain(vnffg_classifier.rsp_id,flow_classifier_list) + drv.update_port_chain(vnffg_classifier.rsp_id, flow_classifier_list) return flow_classifier_list @rwstatus(ret_on_failure=[None]) -- 2.25.1