From a7181a776cd357e385d28fb1fffb7709e212d604 Mon Sep 17 00:00:00 2001 From: S Sudheer Kosuru Date: Fri, 22 Jul 2022 14:17:18 +0530 Subject: [PATCH] Code fixes in accordance with PEP8 style guide by using pylint to improve code rating from -1.95 to 8.52 --- build.py | 22 +- pylxca/pylxca_api/lxca_api.py | 346 +++++++++++++-------------- pylxca/pylxca_api/lxca_connection.py | 69 +++--- pylxca/pylxca_api/lxca_rest.py | 123 ++++++---- pylxca/pylxca_cmd/__init__.py | 7 +- pylxca/pylxca_cmd/lxca_cmd.py | 101 ++++---- pylxca/pylxca_cmd/lxca_icommands.py | 100 ++++---- pylxca/pylxca_cmd/lxca_ishell.py | 114 +++++---- pylxca/pylxca_cmd/lxca_pyshell.py | 162 ++++++------- pylxca/pylxca_cmd/lxca_view.py | 91 ++++--- setup.py | 8 +- 11 files changed, 583 insertions(+), 560 deletions(-) diff --git a/build.py b/build.py index 4a42f19..b5a91b2 100755 --- a/build.py +++ b/build.py @@ -1,14 +1,18 @@ +""" +Build script to build repository +""" #!/usr/bin/env python # Build Script -import sys,os +import sys +import os import subprocess -if len(sys.argv) < 2 : - print ("Building Repository") - ret = subprocess.call(sys.executable + " setup.py sdist bdist_wheel",shell = True) - print ("Done ", ret) - print ("Build drop location is: ", os.getcwd() + "/dist") +if len(sys.argv)<2 : + print ("Building Repository") + CONST_RET = subprocess.call(sys.executable + " setup.py sdist bdist_wheel", shell = True) + print ("Done ", CONST_RET) + print ("Build drop location is: ", os.getcwd() + "/dist") elif sys.argv[1] == "clean": - ret = subprocess.call(sys.executable + " setup.py clean --all",shell = True) - print ("Done ", ret) -sys.exit(ret) + CONST_RET = subprocess.call(sys.executable + " setup.py clean --all", shell = True) + print ("Done ", CONST_RET) +sys.exit(CONST_RET) diff --git a/pylxca/pylxca_api/lxca_api.py b/pylxca/pylxca_api/lxca_api.py index 17b5f3f..ef8bdec 100644 --- a/pylxca/pylxca_api/lxca_api.py +++ b/pylxca/pylxca_api/lxca_api.py @@ -4,14 +4,12 @@ @license: Lenovo License @copyright: Copyright 2016, Lenovo @organization: Lenovo -@summary: This module implement facade interface for pylxca API interface. It provides a -single entry point for APIs. +@summary: This module implement facade interface for pylxca API interface. +It provides a single entry point for APIs. ''' - import logging.config import json - from pylxca.pylxca_api.lxca_connection import lxca_connection from pylxca.pylxca_api.lxca_connection import ConnectionError from pylxca.pylxca_api.lxca_rest import lxca_rest @@ -20,7 +18,7 @@ logger = logging.getLogger(__name__) class Singleton(type): - + """Singleton class""" def __call__(cls, *args, **kwargs):#@NoSelf try: return cls.__instance @@ -29,25 +27,29 @@ def __call__(cls, *args, **kwargs):#@NoSelf return cls.__instance def with_metaclass(meta, *bases): - class metaclass(meta): + """with metaclass""" + class MetaClass(meta): + """metaclass""" __call__ = type.__call__ __init__ = type.__init__ - def __new__(cls, name, this_bases, d): + def __new__(cls, name, this_bases, argd): if this_bases is None: - return type.__new__(cls, name, (), d) - return meta(name, bases, d) - return metaclass('temporary_class', None, {}) - + return type.__new__(cls, name, (), argd) + return meta(name, bases, argd) + return MetaClass('temporary_class', None, {}) +# pylint: disable=R0904 +# pylint: disable=C0116 +# pylint: disable=C0301 +# pylint: disable=C0103 class lxca_api(with_metaclass(Singleton, object)): + ''' Facade class which exposes interface for accessing various LXCA APIs ''' - def __init__(self): ''' Constructor ''' - self.con = None self.func_dict = {'connect':self.connect, 'disconnect':self.disconnect, @@ -83,13 +85,10 @@ def __init__(self): 'storedcredentials': self.get_set_storedcredentials, 'license': self.get_license } - def api( self, object_name, dict_handler = None, con = None ): - - try: # If Any connection is establibshed - if con == None and self.con and isinstance(self.con,lxca_connection): + if con is None and self.con and isinstance(self.con,lxca_connection): con = self.con if object_name == "disconnect": @@ -100,29 +99,27 @@ def api( self, object_name, dict_handler = None, con = None ): self.con = con else: raise ConnectionError("Invalid Connection Object") - - return self.func_dict[object_name](dict_handler) - except ConnectionError as re: - logger.error("Connection Exception: Exception = %s", re) - if self.con: + except ConnectionError as raised_connection_error: + logger.error("Connection Exception: Exception = %s", raised_connection_error) + if self.con: self.con.disconnect() self.con = None - raise re - except HTTPError as re: - logger.error("Exception %s Occurred while calling REST API for object %s" %(re, object_name)) - raise re - except ValueError as re: - logger.error("Exception ValueError %s Occurred while calling REST API for object %s" %(re, object_name)) - raise re - except AttributeError as re: - logger.error("Exception AttributeError %s Occurred while calling REST API for object %s" %(re, object_name)) - raise re - except Exception as re: - logger.error("Exception: %s %s Occurred while calling REST API for object %s" %(type(re), str(re), object_name)) - raise re + raise raised_connection_error + except HTTPError as raised_connection_error: + logger.error("Exception {%s} Occurred while calling REST API for object {%s}",raised_connection_error , object_name) + raise raised_connection_error + except ValueError as raised_connection_error: + logger.error("Exception ValueError {%s} Occurred while calling REST API for object {%s}", raised_connection_error, object_name) + raise raised_connection_error + except AttributeError as raised_connection_error: + logger.error("Exception AttributeError {%s} Occurred while calling REST API for object {%s}", raised_connection_error, object_name) + raise raised_connection_error + except Exception as raised_connection_error: + logger.error("Exception: {%s} {%s} Occurred while calling REST API for object {%s}",type(raised_connection_error), str(raised_connection_error), object_name) + raise raised_connection_error return None - + def connect( self, dict_handler = None ): url = user = passwd = None verify = True @@ -130,22 +127,23 @@ def connect( self, dict_handler = None ): url = next(item for item in [dict_handler.get('l') , dict_handler.get('url')] if item is not None) user = next(item for item in [dict_handler.get('u') , dict_handler.get('user')] if item is not None) passwd = next(item for item in [dict_handler.get('p') , dict_handler.get('pw')] if item is not None) - if "noverify" in dict_handler: verify = False - + if "noverify" in dict_handler: + verify = False + self.con = lxca_connection(url,user,passwd,verify) - + #clear the temp stored passwd passwd = None - - if self.con.connect() == True: + + if self.con.connect() is True: self.con.test_connection() logger.debug("Connection to LXCA Success") - return self.con + return self.con else: logger.error("Connection to LXCA Failed") self.con = None return self.con - + def disconnect( self, dict_handler=None): """ this method perform disconnect operation @@ -174,7 +172,8 @@ def disconnect( self, dict_handler=None): reset_conn_to_orig = True try: resp = self.con.disconnect() - except Exception as e: + except Exception as connectexception: + logger.error("Exception {%s} Occurred while disconnecting",connectexception) if reset_conn_to_orig: self.con = dict_handler['orig_con'] raise @@ -188,18 +187,18 @@ def get_log_level(self, dict_handler=None): lvl = None if dict_handler: lvl = next((item for item in [dict_handler.get('l') , dict_handler.get('lvl')] if item is not None),None) - if lvl == None: + if lvl is None: lvl = lxca_rest().get_log_level() else: return self.set_log_level(lvl) return lvl - + def set_log_level(self, log_value): try: lxca_rest().set_log_level(log_value) - logger.debug("Current Log Level is now set to " + str(logger.getEffectiveLevel())) - except Exception as e: - logger.error("Fail to set Log Level") + logger.debug("Current Log Level is now set to {%s} ",str(logger.getEffectiveLevel())) + except Exception as loglevelexception: + logger.error("Fail to set Log Level{%s}",loglevelexception) return False return True @@ -208,30 +207,30 @@ def get_chassis( self, dict_handler = None ): status = None if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: uuid = next((item for item in [dict_handler.get('u') , dict_handler.get('uuid')] if item is not None),None) status = next((item for item in [dict_handler.get('s') , dict_handler.get('status')] if item is not None),None) - + resp = lxca_rest().get_chassis(self.con.get_url(),self.con.get_session(),uuid,status) py_obj = json.loads(resp.text) return py_obj - + def get_nodes( self, dict_handler = None ): uuid = None status = None chassis_uuid = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: uuid = next((item for item in [dict_handler.get('u') , dict_handler.get('uuid')] if item is not None),None) modify = next((item for item in [dict_handler.get('m'), dict_handler.get('modify')] if item is not None), None) status = next((item for item in [dict_handler.get('s') , dict_handler.get('status')] if item is not None),None) chassis_uuid = next((item for item in [dict_handler.get('c') , dict_handler.get('chassis')] if item is not None),None) metrics = next((True for item in [dict_handler.get('x', False), dict_handler.get('metrics', False)] if item is None or item is True), False) - + if chassis_uuid: resp = lxca_rest().get_chassis(self.con.get_url(),self.con.get_session(),chassis_uuid,status) py_obj = json.loads(resp.text) @@ -248,7 +247,7 @@ def get_nodes( self, dict_handler = None ): resp = lxca_rest().get_nodes(self.con.get_url(),self.con.get_session(),uuid,status) py_obj = json.loads(resp.text) return py_obj - + def get_switches( self, dict_handler = None ): uuid = None chassis_uuid = None @@ -258,7 +257,7 @@ def get_switches( self, dict_handler = None ): if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: uuid = next((item for item in [dict_handler.get('u') , dict_handler.get('uuid')] if item is not None),None) chassis_uuid = next((item for item in [dict_handler.get('c') , dict_handler.get('chassis')] if item is not None),None) @@ -266,13 +265,14 @@ def get_switches( self, dict_handler = None ): action = next((item for item in [dict_handler.get('action')] if item is not None), None) #if "ports" in dict_handler: list_port = True - if port_name: list_port = True + if port_name: + list_port = True if chassis_uuid: resp = lxca_rest().get_chassis(self.con.get_url(),self.con.get_session(),chassis_uuid,None) py_obj = json.loads(resp.text) py_obj = {'switchesList':py_obj["switches"]} - elif list_port and (action==None): + elif list_port and (action is None): resp = lxca_rest().get_switches_port(self.con.get_url(), self.con.get_session(), uuid, list_port) py_obj = json.loads(resp.text) elif port_name and action: @@ -282,18 +282,18 @@ def get_switches( self, dict_handler = None ): resp = lxca_rest().get_switches(self.con.get_url(),self.con.get_session(),uuid) py_obj = json.loads(resp.text) return py_obj - + def get_fans( self, dict_handler = None ): uuid = None chassis_uuid = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: uuid = next((item for item in [dict_handler.get('u') , dict_handler.get('uuid')] if item is not None),None) chassis_uuid = next((item for item in [dict_handler.get('c') , dict_handler.get('chassis')] if item is not None),None) - + if chassis_uuid: resp = lxca_rest().get_chassis(self.con.get_url(),self.con.get_session(),chassis_uuid,None) py_obj = json.loads(resp.text) @@ -306,14 +306,14 @@ def get_fans( self, dict_handler = None ): def get_powersupply( self, dict_handler = None ): uuid = None chassis_uuid = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: uuid = next((item for item in [dict_handler.get('u') , dict_handler.get('uuid')] if item is not None),None) chassis_uuid = next((item for item in [dict_handler.get('c') , dict_handler.get('chassis')] if item is not None),None) - + if chassis_uuid: resp = lxca_rest().get_chassis(self.con.get_url(),self.con.get_session(),chassis_uuid,None) py_obj = json.loads(resp.text) @@ -322,18 +322,18 @@ def get_powersupply( self, dict_handler = None ): resp = lxca_rest().get_powersupply(self.con.get_url(),self.con.get_session(),uuid) py_obj = json.loads(resp.text) return py_obj - + def get_fanmux( self, dict_handler = None ): uuid = None chassis_uuid = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: uuid = next((item for item in [dict_handler.get('u') , dict_handler.get('uuid')] if item is not None),None) chassis_uuid = next((item for item in [dict_handler.get('c') , dict_handler.get('chassis')] if item is not None),None) - + if chassis_uuid: resp = lxca_rest().get_chassis(self.con.get_url(),self.con.get_session(),chassis_uuid,None) py_obj = json.loads(resp.text) @@ -346,14 +346,14 @@ def get_fanmux( self, dict_handler = None ): def get_cmm( self, dict_handler = None ): uuid = None chassis_uuid = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: uuid = next((item for item in [dict_handler.get('u') , dict_handler.get('uuid')] if item is not None),None) chassis_uuid = next((item for item in [dict_handler.get('c') , dict_handler.get('chassis')] if item is not None),None) - + if chassis_uuid: resp = lxca_rest().get_chassis(self.con.get_url(),self.con.get_session(),chassis_uuid,None) py_obj = json.loads(resp.text) @@ -369,7 +369,7 @@ def get_scalablesystem( self, dict_handler = None ): if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: complexid = next((item for item in [dict_handler.get('i') , dict_handler.get('id')] if item is not None),None) complextype = next((item for item in [dict_handler.get('t') , dict_handler.get('type')] if item is not None),None) @@ -381,21 +381,21 @@ def get_scalablesystem( self, dict_handler = None ): def do_discovery( self, dict_handler = None ): ip_addr = None jobid = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: ip_addr = next((item for item in [dict_handler.get ('i') , dict_handler.get('ip')] if item is not None),None) jobid = next((item for item in [dict_handler.get ('j') , dict_handler.get('job')] if item is not None),None) - + resp = lxca_rest().do_discovery(self.con.get_url(),self.con.get_session(),ip_addr,jobid) - + try: py_obj = resp return py_obj - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror def do_manage( self, dict_handler = None ): ip_addr = None @@ -405,10 +405,10 @@ def do_manage( self, dict_handler = None ): jobid = None force = None storedcredential_id = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: ip_addr = next((item for item in [dict_handler.get ('i') , dict_handler.get('ip')] if item is not None),None) user = next((item for item in [dict_handler.get ('u') , dict_handler.get('user')] if item is not None),None) @@ -421,35 +421,35 @@ def do_manage( self, dict_handler = None ): resp = lxca_rest().do_manage(self.con.get_url(),self.con.get_session(),ip_addr,user, pw,rpw,force,jobid, storedcredential_id) - + try: py_obj = resp return py_obj - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror def do_unmanage( self, dict_handler = None ): endpoints = None force = None jobid = None - + if not self.con: raise ConnectionError("Connection is not Initialized.") - + if dict_handler: endpoints = next((item for item in [dict_handler.get ('e') , dict_handler.get('ep')] if item is not None),None) force = next((item for item in [dict_handler.get ('f') , dict_handler.get('force')] if item is not None),False) jobid = next((item for item in [dict_handler.get ('j') , dict_handler.get('job')] if item is not None),None) - + resp = lxca_rest().do_unmanage(self.con.get_url(),self.con.get_session(),endpoints,force,jobid) - + try: py_obj = resp - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj - + def get_configtargets( self, dict_handler = None ): targetid = None @@ -465,13 +465,13 @@ def get_configtargets( self, dict_handler = None ): py_obj = json.loads(resp.text) return py_obj - except AttributeError as ValueError: - raise ValueError - + except AttributeError as valueerror: + raise valueerror + def do_configpatterns( self, dict_handler = None ): patternid = None patternname = None - includeSettings = None + includesettings = None endpoint = None restart = None etype = None @@ -487,7 +487,7 @@ def do_configpatterns( self, dict_handler = None ): patternid = next((item for item in [dict_handler.get ('i') , dict_handler.get('id')] if item is not None),None) patternname = next((item for item in [dict_handler.get('n'), dict_handler.get('name')] if item is not None), None) - includeSettings = next((item for item in [dict_handler.get('includeSettings')] if item is not None),None) + includesettings = next((item for item in [dict_handler.get('includeSettings')] if item is not None),None) endpoint = next((item for item in [dict_handler.get ('e') , dict_handler.get('endpoint')] if item is not None),None) restart = next((item for item in [dict_handler.get ('r') , dict_handler.get('restart')] if item is not None),None) etype = next((item for item in [dict_handler.get ('t') , dict_handler.get('type')] if item is not None),None) @@ -503,11 +503,11 @@ def do_configpatterns( self, dict_handler = None ): patternid = item['id'] break if not patternid: - raise Exception("Pattern Name %s not found" %patternname) + raise Exception(f"Pattern Name {patternname} not found") if subcmd == 'status': resp = lxca_rest().get_configstatus(self.con.get_url(), self.con.get_session(), endpoint) else: - resp = lxca_rest().do_configpatterns(self.con.get_url(),self.con.get_session(),patternid, includeSettings, endpoint, restart, etype, pattern_update_dict) + resp = lxca_rest().do_configpatterns(self.con.get_url(),self.con.get_session(),patternid, includesettings, endpoint, restart, etype, pattern_update_dict) # if endpoint: # return resp @@ -515,17 +515,16 @@ def do_configpatterns( self, dict_handler = None ): py_obj = json.loads(resp.text) return py_obj - except HTTPError as e: - logger.error(e) - if e.response.status_code == 403: - return e.response.json() + except HTTPError as errorhttp: + logger.error(errorhttp) + if errorhttp.response.status_code == 403: + return errorhttp.response.json() else: - logger.error("Exception %s Occurred while calling REST API" %(e)) - raise e + logger.error("Exception {%s} Occurred while calling REST API",errorhttp) + raise errorhttp + except AttributeError as valueerror: + raise valueerror - except AttributeError as ValueError: - raise ValueError - def get_configprofiles( self, dict_handler = None ): profileid = None profilename = None @@ -586,18 +585,18 @@ def get_configprofiles( self, dict_handler = None ): elif resp.status_code == 204: # Its success for rename of profile with empty text return { 'ID':profileid, 'name':profilename} - except HTTPError as e: - logger.error(e) - if e.response.status_code == 403: - return e.response.json() + except HTTPError as errorhttp: + logger.error(errorhttp) + if errorhttp.response.status_code == 403: + return errorhttp.response.json() else: - logger.error("Exception %s Occurred while calling REST API" %(e)) - raise e + logger.error("Exception %s Occurred while calling REST API",errorhttp) + raise errorhttp - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror - def get_jobs( self, dict_handler = None ): + def get_jobs( self, dict_handler = None ): jobid = None uuid = None state = None @@ -627,8 +626,8 @@ def get_jobs( self, dict_handler = None ): py_obj = json.loads(resp.text) py_obj = {'jobsList':py_obj} return py_obj - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror @@ -644,19 +643,18 @@ def get_users( self, dict_handler = None ): resp = lxca_rest().get_users(self.con.get_url(),self.con.get_session(),userid) try: - + if userid: py_obj = json.loads(resp.text)['response'] else: py_obj = json.loads(resp.text) py_obj = {'usersList':py_obj['response']} - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj - def get_lxcalog( self, dict_handler = None ): + def get_lxcalog( self, dict_handler = None ): filter = None - if not self.con: raise ConnectionError("Connection is not Initialized.") @@ -669,8 +667,8 @@ def get_lxcalog( self, dict_handler = None ): py_obj = json.loads(resp.text) py_obj = {'eventList':py_obj} return py_obj - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror def get_ffdc( self, dict_handler = None ): uuid = None @@ -685,8 +683,8 @@ def get_ffdc( self, dict_handler = None ): try: py_obj = resp - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj @@ -717,8 +715,8 @@ def do_updatepolicy( self, dict_handler = None ): py_obj = json.loads(resp.text) if info == "RESULTS": py_obj = py_obj["all"] - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj def get_updaterepo( self, dict_handler = None ): @@ -749,8 +747,8 @@ def get_updaterepo( self, dict_handler = None ): try: py_obj = json.loads(resp.text) - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj @@ -782,8 +780,8 @@ def do_managementserver(self, dict_handler=None): try: py_obj = json.loads(resp.text) - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror py_obj['dummy']={'status':[]} return py_obj @@ -813,21 +811,21 @@ def do_updatecomp( self, dict_handler = None ): resp = lxca_rest().do_updatecomp(self.con.get_url(),self.con.get_session(), query, mode,action,server,switch,storage,cmm, dev_list) try: - if mode == None and action == None and server == None and switch == None and storage == None and cmm == None and dev_list == None : + if mode is None and action is None and server is None and switch is None and storage is None and cmm is None and dev_list is None : py_obj = json.loads(resp.text) else: py_obj = resp.json() return py_obj - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj def get_set_tasks(self, dict_handler=None): job_uuid = None - includeChildren = False + includechildren = False action = None - status = None - cmd_updateList = None + #status = None + #cmdupdatelist = None template = None if not self.con: @@ -835,12 +833,12 @@ def get_set_tasks(self, dict_handler=None): if dict_handler: job_uuid = next((item for item in [ dict_handler.get('jobUID')] if item is not None), None) - includeChildren = next((item for item in [ dict_handler.get('children')] if item is not None), "true") + includechildren = next((item for item in [ dict_handler.get('children')] if item is not None), "true") action = next((item for item in [dict_handler.get('action')] if item is not None), None) - updateList = next((item for item in [dict_handler.get('updateList')] if item is not None), None) + updatelist = next((item for item in [dict_handler.get('updateList')] if item is not None), None) template = next((item for item in [dict_handler.get('template')] if item is not None), None) - #if updateList: - # updateList = updateList['taskList'] + #if updatelist: + # updatelist = updatelist['taskList'] if job_uuid and action in ['cancel']: @@ -850,13 +848,13 @@ def get_set_tasks(self, dict_handler=None): resp = lxca_rest().delete_tasks(self.con.get_url(), self.con.get_session(), job_uuid) py_obj = resp.status_code elif action in ['update']: - resp = lxca_rest().put_tasks_update(self.con.get_url(), self.con.get_session(), updateList) + resp = lxca_rest().put_tasks_update(self.con.get_url(), self.con.get_session(), updatelist) py_obj = resp.status_code elif action in ['create']: resp = lxca_rest().post_tasks(self.con.get_url(), self.con.get_session(), template) py_obj = resp else: - resp = lxca_rest().get_tasks(self.con.get_url(), self.con.get_session(), job_uuid, includeChildren) + resp = lxca_rest().get_tasks(self.con.get_url(), self.con.get_session(), job_uuid, includechildren) py_obj = json.loads(resp.text) py_obj = {'TaskList': py_obj[:]} return py_obj @@ -871,14 +869,12 @@ def get_set_manifests( self, dict_handler = None ): if dict_handler: sol_id = next((item for item in [dict_handler.get('i') , dict_handler.get('id')] if item is not None),None) filepath = next((item for item in [dict_handler.get('f') , dict_handler.get('file')] if item is not None),None) - resp = lxca_rest().get_set_manifests(self.con.get_url(),self.con.get_session(),sol_id,filepath) - try: py_obj = resp.json() return py_obj - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj @@ -918,7 +914,7 @@ def get_set_osimage(self, dict_handler = None): try: if dict_handler: osimages_info = next((item for item in [dict_handler.get('subcmd')] if item is not None), None) - imageType = next((item for item in [dict_handler.get('t'), dict_handler.get('imagetype')] if item is not None), None) + imagetype = next((item for item in [dict_handler.get('t'), dict_handler.get('imagetype')] if item is not None), None) id = next((item for item in [dict_handler.get('i'), dict_handler.get('id')] if item is not None), None) action = next((item for item in [dict_handler.get('a'), dict_handler.get('action')] if item is not None), None) @@ -948,7 +944,7 @@ def get_set_osimage(self, dict_handler = None): elif 'import' in osimages_info: if not kwargs: kwargs = {} - kwargs['imageType'] = imageType + kwargs['imageType'] = imagetype resp = lxca_rest().osimage_import(self.con.get_url(), self.con.get_session(), kwargs) elif 'remotefileservers' in osimages_info: if not kwargs: @@ -964,27 +960,27 @@ def get_set_osimage(self, dict_handler = None): py_obj = resp.json() return py_obj - except HTTPError as e: - logger.error(e) - if e.response.status_code == 403: - return e.response.json() + except HTTPError as errorhttp: + logger.error(errorhttp) + if errorhttp.response.status_code == 403: + return errorhttp.response.json() else: - logger.error("Exception %s Occurred while calling REST API" %(e)) - raise e + logger.error("Exception {%s} Occurred while calling REST API",errorhttp) + raise errorhttp except ValueError as err: - logger.error("Exception: Non json response: %s" %(str(err))) + logger.error("Exception: Non json response: {%s}",err) raise err except AttributeError as err: raise err return py_obj def get_set_resourcegroups(self, dict_handler = None): - ''' + '''get_set_resourcegroups ''' - subcmd=uuid = name = desc = type = solutionVPD = members = criteria = None + subcmd=uuid = name = desc = type = solutionvpd = members = criteria = None if not self.con: raise ConnectionError("Connection is not Initialized.") @@ -995,7 +991,7 @@ def get_set_resourcegroups(self, dict_handler = None): name = next((item for item in [dict_handler.get('n') , dict_handler.get('name')] if item is not None),None) desc = next((item for item in [dict_handler.get('d') , dict_handler.get('description')] if item is not None),None) type = next((item for item in [dict_handler.get('t') , dict_handler.get('type')] if item is not None),None) - solutionVPD = next((item for item in [dict_handler.get('s') , dict_handler.get('solutionVPD')] if item is not None),None) + solutionvpd = next((item for item in [dict_handler.get('s') , dict_handler.get('solutionVPD')] if item is not None),None) members = next((item for item in [dict_handler.get('m') , dict_handler.get('members')] if item is not None),None) criteria = next((item for item in [dict_handler.get('c') , dict_handler.get('criteria')] if item is not None),None) subcmd = next( @@ -1018,7 +1014,7 @@ def get_set_resourcegroups(self, dict_handler = None): type, criteria) elif 'solution' in type: resp = lxca_rest().solution_resourcegroups(self.con.get_url(), self.con.get_session(), uuid, name, - desc, type, solutionVPD, members, criteria) + desc, type, solutionvpd, members, criteria) else: raise Exception("Invalid argument: Type supported are dynamic and solution") elif 'update' in subcmd: @@ -1028,14 +1024,14 @@ def get_set_resourcegroups(self, dict_handler = None): type, criteria) elif 'solution' in type: resp = lxca_rest().solution_resourcegroups(self.con.get_url(), self.con.get_session(), uuid, name, - desc, type, solutionVPD, members, criteria) + desc, type, solutionvpd, members, criteria) else: raise Exception("Invalid argument: Type supported are dynamic and solution") try: py_obj = json.loads(resp.text) - except AttributeError as ValueError: - raise ValueError + except AttributeError as valueerror: + raise valueerror return py_obj def get_set_rules(self, dict_handler=None): @@ -1060,9 +1056,9 @@ def get_set_rules(self, dict_handler=None): def get_set_compositeResults(self, dict_handler=None): id = None - query_solutionGroups = None - solutionGroups = None - targetResources = None + query_solutiongroups = None + solutiongroups = None + targetresources = None all_rules = None if not self.con: @@ -1071,25 +1067,25 @@ def get_set_compositeResults(self, dict_handler=None): if dict_handler: id = next((item for item in [dict_handler.get('i'), dict_handler.get('id')] if item is not None), None) - query_solutionGroups = next((item for item in + query_solutiongroups = next((item for item in [dict_handler.get('q'), dict_handler.get('query_solutionGroups')] if item is not None), None) - solutionGroups = next((item for item in [dict_handler.get('s'), + solutiongroups = next((item for item in [dict_handler.get('s'), dict_handler.get('solutionGroups')] if item is not None), None) - targetResources = next( + targetresources = next( (item for item in [dict_handler.get('t'), dict_handler.get('targetResources')] if item is not None), None) all_rules = next( (item for item in [dict_handler.get('a'), dict_handler.get('all_rules')] if item is not None), None) - if all_rules or solutionGroups or targetResources: + if all_rules or solutiongroups or targetresources: resp = lxca_rest().set_compositeResults(self.con.get_url(), - self.con.get_session(), solutionGroups, targetResources, all_rules) + self.con.get_session(), solutiongroups, targetresources, all_rules) else: resp = lxca_rest().get_compositeResults(self.con.get_url(), - self.con.get_session(), id, query_solutionGroups) + self.con.get_session(), id, query_solutiongroups) py_obj = json.loads(resp.text) return py_obj diff --git a/pylxca/pylxca_api/lxca_connection.py b/pylxca/pylxca_api/lxca_connection.py index 565d155..767baf1 100644 --- a/pylxca/pylxca_api/lxca_connection.py +++ b/pylxca/pylxca_api/lxca_connection.py @@ -7,20 +7,20 @@ @summary: This module is for creating a connection session object for given xHMC. ''' - -import requests -import logging, json -import os, platform +import logging +import os +import json +import platform import base64 import pkg_resources -from _socket import timeout -from requests.sessions import session +import requests from requests.adapters import HTTPAdapter from requests.packages.urllib3.poolmanager import PoolManager logger = logging.getLogger(__name__) class lxcaAdapter(HTTPAdapter): + """lxcaAdapter class""" def init_poolmanager(self, connections, maxsize, block=False): @@ -41,7 +41,7 @@ class ConnectionError(Error): class lxca_connection(object): ''' - C + Class lxca connection ''' def __init__(self, url, user = None, passwd = None, verify_callback = True, retries = 3): self.url = url @@ -59,7 +59,7 @@ def __init__(self, url, user = None, passwd = None, verify_callback = True, ret self.verify_callback = verify_callback def __repr__(self): - return "%s(%s, %s, debug=%s)" %(self.__class__.__name__, repr(self.url), self.user, repr(self.debug)) + return f'{self.__class__.__name__} {repr(self.url)}, {self.user}, {repr(self.debug)}' def connect(self): ''' @@ -69,36 +69,31 @@ def connect(self): logger.debug("Establishing Connection") self.session = requests.session() self.session.verify = self.verify_callback - pylxca_version = pkg_resources.require("pylxca")[0].version # Update the headers with your custom ones # You don't have to worry about case-sensitivity with # the dictionary keys, because default_headers uses a custom # CaseInsensitiveDict implementation within requests' source code. self.session.headers.update({'content-type': 'application/json; charset=utf-8','User-Agent': 'LXCA via Python Client / ' + pylxca_version}) - - payload = dict(UserId= self.user, password=base64.b16decode(self.passwd).decode()) pURL = self.url + '/sessions' self.session.mount(self.url, lxcaAdapter(max_retries=self.retires)) - r = self.session.post(pURL,data = json.dumps(payload),headers=dict(Referer=pURL),verify=self.verify_callback, timeout = 3) - r.raise_for_status() - except ConnectionError as e: - logger.debug("Connection Exception as ConnectionError: Exception = %s", e) + responseobj = self.session.post(pURL,data = json.dumps(payload),headers=dict(Referer=pURL),verify=self.verify_callback, timeout = 3) + responseobj.raise_for_status() + except ConnectionError as errorconnection: + logger.debug("Connection Exception as ConnectionError: Exception = {%s}",errorconnection) return False - except requests.exceptions.HTTPError as e: - logger.debug("Connection Exception as HttpError: Exception = %s", e.response.text) + except requests.exceptions.HTTPError as errorhttp: + logger.debug("Connection Exception as HttpError: Exception = {%s}", errorhttp.response.text) return False - except Exception as e: - logger.debug("Connection Exception: Exception = %s", e) + except Exception as exception: + logger.debug("Connection Exception: Exception = {%s}", exception) return False - ''' - Even though the csrf-token cookie will be automatically sent with the request, - the server will be still expecting a valid X-Csrf-Token header, - So we need to set it explicitly here - ''' - if r.status_code == requests.codes['ok']: + #Even though the csrf-token cookie will be automatically sent with the request, + #the server will be still expecting a valid X-Csrf-Token header, + #So we need to set it explicitly here + if responseobj.status_code == requests.codes['ok']: self.session.headers.update({'X-Csrf-Token': self.session.cookies.get('csrf')}) return True @@ -112,14 +107,20 @@ def test_connection(self): resp = self.session.get(test_url,verify=self.session.verify, timeout=3) #If valid JSON object is parsed then the connection is successfull py_obj = resp.json() - except Exception as e: - raise ConnectionError("Invalid connection") - return + logger.debug("response json{%s}", py_obj) + except Exception as defaultexception: + raise ConnectionError("Invalid connection") from defaultexception def get_url(self): + """ + Returns self url + """ return self.url def get_session(self): + """ + Returns session + """ return self.session def disconnect(self): @@ -133,9 +134,9 @@ def disconnect(self): py_obj = resp.json() logger.debug("Deleted session on lxca = %s", py_obj) result = True - except Exception as e: - logger.debug("Unable to delete session on lxca = %s", e) - raise ConnectionError("Invalid connection: Connection is not Initialized") + except Exception as defaultexception: + logger.debug("Unable to delete session on lxca = {%s}", defaultexception) + raise ConnectionError("Invalid connection: Connection is not Initialized") from defaultexception self.url = None self.user = None @@ -143,9 +144,9 @@ def disconnect(self): self.debug = False try: self.session.close() - except Exception as e: - logger.debug("Connection with invalid session = %s", e) - raise Exception("Invalid connection: Connection is not Initialized") + except Exception as defaultexception: + logger.debug("Connection with invalid session = {%s}", defaultexception) + raise Exception("Invalid connection: Connection is not Initialized") from defaultexception self.session = None return result diff --git a/pylxca/pylxca_api/lxca_rest.py b/pylxca/pylxca_api/lxca_rest.py index 94e795c..7508e4e 100644 --- a/pylxca/pylxca_api/lxca_rest.py +++ b/pylxca/pylxca_api/lxca_rest.py @@ -7,16 +7,20 @@ @summary: This module is for creating a connection session object for given xHMC ''' -import logging, os, json, pprint, requests +import logging import logging.config +import os +import json +#import pprint +#import socket +import time +import urllib +import requests + from requests_toolbelt import (MultipartEncoder, MultipartEncoderMonitor) from requests.exceptions import HTTPError -import json, re -import socket -import time -import urllib try: @@ -24,24 +28,35 @@ except: pass -logger_conf_file = "lxca_logger.conf" -pylxca_logger = os.path.join(os.getenv('PYLXCA_API_PATH'), logger_conf_file) +LOGGER_CONF_FILE = "lxca_logger.conf" +pylxca_logger = os.path.join(os.getenv('PYLXCA_API_PATH'), LOGGER_CONF_FILE) logger = logging.getLogger(__name__) REST_TIMEOUT = 60 def callback(encoder): + ''' + callback + ''' # uncomment it to debug, spit lot of data in log file for big upload #logger.debug("Callback called with data length %d" % (encoder.bytes_read)) pass - +# pylint: disable=C0103 +# pylint: disable=C0303 +# pylint: disable=C0301 +# pylint: disable=C0116 +# pylint: disable=R0904 +# pylint: disable=R0205 class lxca_rest(object): ''' classdocs ''' def get_chassis(self,url, session, uuid, status ): + ''' + get_chassis + ''' url = url + '/chassis' if uuid: @@ -55,9 +70,9 @@ def get_chassis(self,url, session, uuid, status ): try: resp = session.get(url,verify=False,timeout=REST_TIMEOUT) resp.raise_for_status() - except HTTPError as re: - logger.error("REST API Exception: Exception = %s", re) - raise re + except HTTPError as errorhttp: + logger.error("REST API Exception: Exception = {%s}", errorhttp) + raise errorhttp return resp def get_metrics(self, url, session, uuid ): @@ -101,7 +116,7 @@ def set_nodes(self, url, session, uuid, modify): url = url + '/' + uuid + '?synchronous=false' try: - payload = dict() + payload = {} payload = modify resp = session.put(url, data=json.dumps(payload), verify=False, timeout=REST_TIMEOUT) @@ -113,10 +128,8 @@ def set_nodes(self, url, session, uuid, modify): except HTTPError as re: logger.error("REST API Exception: Exception = %s", re) raise re - return job - def get_switches(self,url, session, uuid): url = url + '/switches' @@ -308,7 +321,7 @@ def do_manage(self,url, session, ip_addr,user,pw,rpw,force,jobid, storedcredenti url = url + '/manageRequest' payload = list() - param_dict = dict() + param_dict = {} param_dict["ipAddresses"]=ip_addr.split(",") param_dict["username"] = user @@ -419,14 +432,14 @@ def do_manage(self,url, session, ip_addr,user,pw,rpw,force,jobid, storedcredenti def do_unmanage(self,url, session, endpoints,force,jobid): endpoints_list = list() - param_dict = dict() + param_dict = {} try: if endpoints: url = url + '/unmanageRequest' for each_ep in endpoints.split(","): ip_addr = None - each_ep_dict = dict() + each_ep_dict = {} ep_data = each_ep.split(";") ip_addr = ep_data[0] @@ -602,7 +615,7 @@ def get_updatepolicy(self, url, session, info, jobid, uuid): return resp elif jobid: url = url + "/compareResult" - payload = dict() + payload = {} payload["jobid"] = jobid payload["uuid"] = uuid resp = session.get(url, data = json.dumps(payload), verify=False, timeout=REST_TIMEOUT) @@ -625,9 +638,9 @@ def post_updatepolicy(self, url, session, policy, type, uuid): if not policy or not type or not uuid: raise Exception("Invalid argument key") - payload = dict() + payload = {} - policy_dict = dict() + policy_dict = {} policy_dict["policyName"] = policy # do auto discovery @@ -710,7 +723,7 @@ def put_updaterepo(self, url, session, action , fixids, mt, type, scope): else: raise Exception("Invalid argument scope:" + scope) - payload = dict() + payload = {} if action == "delete": if fixids: fixids_list = fixids.split(",") @@ -773,7 +786,7 @@ def get_managementserver(self, url, session, key, fixids, type): def set_managementserver(self, url, session, action, files, jobid, fixids): url = url + '/managementServer/updates' try: - if not action == None \ + if not action is None \ and action == "apply": # implement PUT url = url + "?action=apply" @@ -786,14 +799,14 @@ def set_managementserver(self, url, session, action, files, jobid, fixids): resp = session.put(url, data=json.dumps(payload), verify=False, timeout=REST_TIMEOUT) return resp # Creations of Import job POST - if not action == None and action == "import": + if not action is None and action == "import": file_list = files.strip().split(",") file_type_dict = {'.txt': 'text/plain', '.xml': 'text/xml', '.chg': 'application/octet-stream', '.tgz': 'application/x-compressed'} - if jobid == None: + if jobid is None: url = url + "?action=import" #payload = {"files":[{"index":0,"name":"lnvgy_sw_lxca_thinksystemrepo1-1.3.2_anyos_noarch.xml","size":7329,"type":"text/xml"}]} payload_files = [{ @@ -819,7 +832,7 @@ def set_managementserver(self, url, session, action, files, jobid, fixids): resp = session.post(url, data = monitor, headers={'Content-Type': monitor.content_type}, verify=False, timeout=100 * REST_TIMEOUT) return resp - if not action == None \ + if not action is None \ and action == "acquire": url = url + "?action=acquire" payload = {} @@ -831,7 +844,7 @@ def set_managementserver(self, url, session, action, files, jobid, fixids): resp = session.post(url, data=json.dumps(payload), verify=False, timeout=REST_TIMEOUT) return resp - if not action == None \ + if not action is None \ and action == "refresh": url = url + "?action=refresh" payload = {} @@ -839,7 +852,7 @@ def set_managementserver(self, url, session, action, files, jobid, fixids): resp = session.post(url, data=json.dumps(payload), verify=False, timeout=REST_TIMEOUT) return resp - if not action == None \ + if not action is None \ and action == "delete": # implement delete if fixids: @@ -870,7 +883,7 @@ def do_updatecomp(self, url, session, query, mode, action, server, switch, stora try: # For Query Action - if mode == None and action == None and server == None and switch == None and storage == None and cmm == None: + if mode is None and action is None and server is None and switch is None and storage is None and cmm is None: if query and query.lower() == 'components': url = url + "?action=getComponents" resp = session.get(url, verify=False, timeout=REST_TIMEOUT) @@ -882,7 +895,7 @@ def do_updatecomp(self, url, session, query, mode, action, server, switch, stora url= url + "?action=" + action - if not mode == None and mode == "immediate" or mode == "delayed" or mode == "prioritized": + if not mode is None and mode == "immediate" or mode == "delayed" or mode == "prioritized": url= url + "&activationMode=" + mode else: if action != "applyBundle": @@ -942,13 +955,17 @@ def do_updatecomp(self, url, session, query, mode, action, server, switch, stora cmm_data = cmm.split(",") cmmlist = [{"UUID": cmm_data[0],"PowerState": cmm_data[1]}] - param_dict = dict() - if serverlist:param_dict["ServerList"] = serverlist - if storagelist:param_dict["StorageList"] = storagelist - if cmmlist:param_dict["CMMList"] = cmmlist - if switchlist:param_dict["SwitchList"] = switchlist + param_dict = {} + if serverlist: + param_dict["ServerList"] = serverlist + if storagelist: + param_dict["StorageList"] = storagelist + if cmmlist: + param_dict["CMMList"] = cmmlist + if switchlist: + param_dict["SwitchList"] = switchlist - payload = dict() + payload = {} payload["DeviceList"] = [param_dict] logger.debug("Update Firmware payload: " + str(payload)) resp = session.put(url,data = json.dumps(payload),verify=False, timeout=REST_TIMEOUT) @@ -966,7 +983,7 @@ def do_updatecomp_all(self, url, session, action, mode, dev_list): if action == "apply" or action == "applyBundle" or action == "cancelApply": url = url + "?action=" + action - if not mode == None and mode == "immediate" or mode == "delayed" or mode == "prioritized": + if not mode is None and mode == "immediate" or mode == "delayed" or mode == "prioritized": url = url + "&activationMode=" + mode else: if action != "applyBundle": @@ -974,7 +991,7 @@ def do_updatecomp_all(self, url, session, action, mode, dev_list): else: raise Exception("Invalid argument action") - #payload = dict() + #payload = {} #payload["DeviceList"] = dev_list payload_data = json.dumps(dev_list) logger.debug("Update Firmware payload: " + str(payload_data)) @@ -1010,7 +1027,7 @@ def put_configprofiles(self, url, session, profileid, profilename): raise Exception("Invalid argument ") try: - payload = dict() + payload = {} payload['profileName'] = profilename resp = session.put(url, data=json.dumps(payload), verify=False, timeout=REST_TIMEOUT) resp.raise_for_status() @@ -1028,7 +1045,7 @@ def post_configprofiles(self, url, session, profileid, endpoint, restart): raise Exception("Invalid argument ") try: - payload = dict() + payload = {} if restart and endpoint: payload['restart'] = restart payload['uuid'] = endpoint @@ -1064,7 +1081,7 @@ def unassign_configprofiles(self, url, session, profileid, powerdown, resetimm, else: raise Exception("Invalid argument, profile id is required for unassign ") - payload = dict() + payload = {} if powerdown: if powerdown.lower() == "true": payload['powerDownITE'] = True @@ -1104,7 +1121,7 @@ def _validate_uuids(self, uuids): uuids_list = uuids.split(",") for uuid in uuids_list: if len(uuid) < 16: - raise Exception("Invalid Arguments, uuid : %s" %uuid) + raise Exception(f'Invalid Arguments, uuid : {uuid}') @@ -1133,7 +1150,7 @@ def do_configpatterns(self, url, session, id, includeSettings, endpoint, restart if endpoint: self._validate_uuids(endpoint) - if id != None: + if id is not None: if len(id) == 0: raise Exception("Invalid Argument, id ") elif not id.isdigit(): @@ -1145,7 +1162,7 @@ def do_configpatterns(self, url, session, id, includeSettings, endpoint, restart try: if endpoint and restart and etype: - param_dict = dict() + param_dict = {} if etype.lower() == 'node' or etype.lower() == 'rack' or etype.lower() == 'tower': param_dict['uuid'] = [endpoint] @@ -1157,7 +1174,7 @@ def do_configpatterns(self, url, session, id, includeSettings, endpoint, restart payload = param_dict resp = session.post(url, data = json.dumps(payload), verify=False, timeout=REST_TIMEOUT) elif pattern_update_dict: - payload = dict() + payload = {} payload = pattern_update_dict resp = session.post(url, data=json.dumps(payload), verify=False, timeout=REST_TIMEOUT) else: @@ -1291,7 +1308,7 @@ def put_tasks_update(self, url, session, updated_dict): def get_set_manifests(self,url, session, sol_id, filepath): resp = None - param_dict = dict() + param_dict = {} url = url + '/manifests' try: @@ -1304,7 +1321,7 @@ def get_set_manifests(self,url, session, sol_id, filepath): if filepath: param_dict['filepath'] = filepath - payload = dict() + payload = {} payload = param_dict resp = session.post(url,data = json.dumps(payload),verify=False, timeout=REST_TIMEOUT) else: @@ -1361,7 +1378,7 @@ def dynamic_resourcegroups(self, url, session, uuid, name, desc, type, criteria) try: - param_dict = dict() + param_dict = {} param_dict['name'] = name param_dict['description'] = desc param_dict['type'] = type @@ -1394,7 +1411,7 @@ def solution_resourcegroups(self, url, session, uuid, name, desc, type, solution if members: payload = [] for dev in members: - param_dict = dict() + param_dict = {} param_dict['op'] = 'add' param_dict["path"] = "/members/-" param_dict["value"] = dev @@ -1404,7 +1421,7 @@ def solution_resourcegroups(self, url, session, uuid, name, desc, type, solution resp.raise_for_status() return resp elif name: - param_dict = dict() + param_dict = {} param_dict['name'] = name param_dict['description'] = desc param_dict['type'] = type @@ -1420,7 +1437,7 @@ def solution_resourcegroups(self, url, session, uuid, name, desc, type, solution param_dict['members'] = members param_dict['criteria'] = None - payload = dict() + payload = {} payload = param_dict resp = session.post(url, data = json.dumps(payload), verify=False, timeout=REST_TIMEOUT) @@ -1805,7 +1822,7 @@ def set_compositeResults(self, url, session, solutionGroups, targetResources, al resp.raise_for_status() return resp - payload = dict() + payload = {} if solutionGroups: payload['solutionGroups'] = solutionGroups elif targetResources: @@ -1853,7 +1870,7 @@ def post_storedcredentials(self, url, session, user_name, password, description) url = url + '/storedCredentials' try: - payload = dict() + payload = {} payload['userName'] = user_name payload['password'] = password payload['description'] = description @@ -1887,7 +1904,7 @@ def put_storedcredentials(self, url, session, id, user_name, password, descripti raise Exception("Invalid Arguments, userName and password are mandatory for put operation only") try: - payload = dict() + payload = {} payload['userName'] = user_name payload['password'] = password payload['description'] = description diff --git a/pylxca/pylxca_cmd/__init__.py b/pylxca/pylxca_cmd/__init__.py index b38a27f..0f893dc 100644 --- a/pylxca/pylxca_cmd/__init__.py +++ b/pylxca/pylxca_cmd/__init__.py @@ -4,11 +4,12 @@ #setting CMD_PATH environment variable to be used in submodules for loading data files import os -pylxca_cmd_path = os.path.dirname(__file__) -os.environ['PYLXCA_CMD_PATH'] = pylxca_cmd_path +import pylxca.pylxca_cmd # All submodules of this package are imported; so clients need to import just this package. from pylxca.pylxca_cmd import lxca_ishell from pylxca.pylxca_cmd import lxca_icommands from pylxca.pylxca_api import * -import pylxca.pylxca_cmd \ No newline at end of file + +pylxca_cmd_path = os.path.dirname(__file__) +os.environ['PYLXCA_CMD_PATH'] = pylxca_cmd_path diff --git a/pylxca/pylxca_cmd/lxca_cmd.py b/pylxca/pylxca_cmd/lxca_cmd.py index 7617d0c..756049c 100644 --- a/pylxca/pylxca_cmd/lxca_cmd.py +++ b/pylxca/pylxca_cmd/lxca_cmd.py @@ -3,23 +3,26 @@ @author: Prashant Bhosale @license: Lenovo License @copyright: Copyright 2016, Lenovo -@organization: Lenovo -@summary: This module provides command class implementation for PyLXCA +@organization: Lenovo +@summary: This module provides command class implementation for PyLXCA ''' - -import sys, getopt -import logging, traceback from getpass import getpass +#import sys +#import getopt +import logging +#import traceback import json -import argparse - +#import argparse import pylxca.pylxca_api + from pylxca.pylxca_api.lxca_rest import HTTPError from pylxca.pylxca_api.lxca_connection import ConnectionError from pylxca.pylxca_cmd.lxca_icommands import InteractiveCommand logger = logging.getLogger(__name__) - +# pylint: disable=C0103 +# pylint: disable=C0303 +# pylint: disable=C0301 class connect(InteractiveCommand): """ Connects to the LXCA Interface @@ -27,7 +30,6 @@ class connect(InteractiveCommand): USAGE: connect -h | --help connect -l -u [--noverify] - OPTIONS: -h This option displays command usage information -l, --url URL of LXCA @@ -52,82 +54,72 @@ def handle_command(self, opts, args): for opt, arg in opts: if '-h' in opt: self.sprint (self.__doc__) - return + return if not opts: self.handle_no_input() return - opt_dict = self.parse_args(opts, argv) ''' try: opt_dict = self.parse_args(args) - if opt_dict.get('pw', None) == None: + if opt_dict.get('pw', None) is None: opt_dict ['pw'] = getpass("Enter Password: ") - except SystemExit as e: + except SystemExit: # ignore this as we need to continue on shell return out_obj = None - try: out_obj = self.handle_input(opt_dict) self.handle_output(out_obj) - except HTTPError as re: - self.sprint("Exception %s occurred while executing command."%(re)) - except ConnectionError as re: - self.sprint("Exception %s occurred while executing command."%(re)) + except HTTPError as httperror: + self.sprint("Exception %s occurred while executing command."%(httperror)) + except ConnectionError as connectionerror: + self.sprint("Exception %s occurred while executing command."%(connectionerror)) except RuntimeError: self.sprint("Session Error to LXCA, Try connect") except Exception as err: self.sprint("Exception occurred: %s" %(err)) - return out_obj - def handle_no_input(self,con_obj = None): #no_opt action can differ command to command so override this function if required self.invalid_input_err() return - def handle_output(self, out_obj): - if out_obj == None: + if out_obj is None: self.sprint("Failed to connect given LXCA " ) else: self.sprint("Connection to LXCA successful") return - ############################################################################### - class disconnect(InteractiveCommand): """ - Diconnects from LXCA Interface - + Diconnects from LXCA Interface USAGE: disconnect -h | --help disconnect """ def handle_no_input(self, con_obj = None): api = pylxca.pylxca_api.lxca_api() - if api.disconnect() == True: + if api.disconnect() is True: self.sprint("Connection with LXCA closed successfully " ) else: self.sprint("Failed to close connection with LXCA " ) - return + ############################################################################### class log(InteractiveCommand): """ Retrieve and configure logging of LXCA Python tool - USAGE: log -h | --help log [-l ] OPTIONS: -l, --lvl Logging level - """ def handle_no_input(self,con_obj = None): api = pylxca.pylxca_api.lxca_api() @@ -142,12 +134,12 @@ def handle_no_input(self,con_obj = None): \tCRITICAL: A serious error, indicating that the program itself may be unable to continue running. """ self.sprint(message) - return + ## custom def for inline activites def handle_output(self, out_obj): api = pylxca.pylxca_api.lxca_api() - if out_obj == True: + if out_obj is True: self.sprint("Current Log Level is set to " + api.get_log_level()) else: self.sprint("Fail to set Log Level") @@ -167,7 +159,7 @@ def handle_output(self, out_obj): class ostream(InteractiveCommand): """ - Configure output stream or verbose level of command shell + Configure output stream or verbose level of command shell USAGE: ostream -h | --help @@ -189,7 +181,7 @@ def handle_no_input(self,con_obj = None): \t3:Console and File. """ self.sprint(message) - return + return def handle_input(self, dict_handler, con_obj = None): lvl = None @@ -200,7 +192,7 @@ def handle_input(self, dict_handler, con_obj = None): ## custom def for inline activites def handle_output(self, out_obj): - if out_obj == True: + if out_obj is True: self.sprint("Current ostream level is set to %s" %(self.shell.ostream.get_lvl())) else: self.sprint("Fail to set ostream Level") @@ -282,7 +274,7 @@ def handle_command(self, opts, args): try: i = args.index('--ports') if i < (no_args - 1): - next_args = args[i + 1]; + next_args = args[i + 1] if next_args.startswith("-"): change = True else: @@ -420,11 +412,11 @@ class jobs(InteractiveCommand): """ def handle_output(self, out_obj): - if out_obj == None: + if out_obj is None: self.sprint("Jobs command Failed." ) - elif out_obj == False: + elif out_obj is False: self.sprint("Jobs command Failed." ) - elif out_obj == True: + elif out_obj is True: self.sprint("Jobs command succeeded" ) return @@ -444,14 +436,14 @@ class discover(InteractiveCommand): """ def handle_output(self, out_obj): - if out_obj == None: + if out_obj is None: self.sprint("Failed to start Discovery job for selected endpoint " ) elif type(out_obj) == str: self.sprint("Discovery job started, jobId = " + out_obj) else: self.sprint(out_obj) return - + class manage(InteractiveCommand): """ Manage the endpoint. @@ -477,19 +469,19 @@ class manage(InteractiveCommand): -v, --view view filter name """ def handle_output(self, out_obj): - if out_obj == None: + if out_obj is None: self.sprint("Failed to start manage job for selected endpoint " ) else: self.sprint("Manage job started, jobId = " + out_obj) return - + def show_output(self, out_obj, view_filter='default'): - if out_obj == None: + if out_obj is None: self.sprint("Failed to start manage job for selected endpoint " ) else: self.sprint("Manage job started, = " + json.dumps(out_obj)) return - + class unmanage(InteractiveCommand): """ Unmanage the endpoint @@ -517,14 +509,14 @@ class unmanage(InteractiveCommand): """ def handle_output(self, out_obj): - if out_obj == None: + if out_obj is None: self.sprint("Failed to start unmanage job for selected endpoint " ) else: self.sprint("Unmanage job started, jobId = " + out_obj) return - + def show_output(self, out_obj, view_filter='default'): - if out_obj == None: + if out_obj is None: self.sprint("Failed to start unmanage job for selected endpoint " ) else: self.sprint("Unmanage job started, = " + json.dumps(out_obj)) @@ -553,14 +545,14 @@ class ffdc(InteractiveCommand): -u, --uuid """ def handle_output(self, out_obj): - if out_obj == None: + if out_obj is None: self.sprint("Failed to start ffdc job for selected endpoint " ) else: self.sprint("FFDC job started, jobId = " + out_obj) return def show_output(self, out_obj, view_filter='default'): - if out_obj == None: + if out_obj is None: self.sprint("Failed to start ffdc job for selected endpoint " ) else: self.sprint("FFDC job started, jobId = " + out_obj) @@ -691,7 +683,7 @@ class updatecomp(InteractiveCommand): """ - + ############################################################################### class configtargets(InteractiveCommand): """ @@ -829,7 +821,7 @@ class osimages(InteractiveCommand): """ OSImages/Deployment on LXCA """ - + def handle_output(self, out_obj): if ( 'result' in out_obj and @@ -841,7 +833,7 @@ def handle_output(self, out_obj): else: self.sprint(out_obj) return - + def show_output(self, out_obj, view_filter='default'): if ( 'result' in out_obj and @@ -911,7 +903,7 @@ class license(InteractiveCommand): def handle_output(self, out_obj): self.sprint(out_obj) return - + def show_output(self, out_obj, view_filter='default'): out_obj['response'][1]['notifications'] = out_obj['response'][1]['notifications'].pop() out_obj['response'] = [self.merge_two_dicts(out_obj['response'][0], out_obj['response'][1])] @@ -919,6 +911,7 @@ def show_output(self, out_obj, view_filter='default'): return def merge_two_dicts(self, x, y): + """ merge_two_dicts""" z = x.copy() z.update(y) return z diff --git a/pylxca/pylxca_cmd/lxca_icommands.py b/pylxca/pylxca_cmd/lxca_icommands.py index ea2905f..599286f 100644 --- a/pylxca/pylxca_cmd/lxca_icommands.py +++ b/pylxca/pylxca_cmd/lxca_icommands.py @@ -3,42 +3,47 @@ @author: Girish Kumar , Prashant Bhosale @license: Lenovo License @copyright: Copyright 2016, Lenovo -@organization: Lenovo -@summary: This module provides interactive command class which provides base -implementation for all command classes +@organization: Lenovo +@summary: This module provides interactive command class which provides base +implementation for all command classes ''' -import sys,getopt,os,json,logging, traceback +import sys +import os +import json +import traceback import argparse -from pylxca.pylxca_api import lxca_api +import textwrap +import ast +from pylxca.pylxca_api import LxcaApi from pylxca.pylxca_api.lxca_rest import HTTPError from pylxca.pylxca_api.lxca_connection import ConnectionError from pylxca.pylxca_cmd import lxca_view -import textwrap -import ast -cmd_data_json_file = "lxca_cmd_data.json" -pylxca_cmd_data = os.path.join(os.getenv('PYLXCA_CMD_PATH'), cmd_data_json_file) +CMD_DATA_JSON_FILE = "lxca_cmd_data.json" +pylxca_cmd_data = os.path.join(os.getenv('PYLXCA_CMD_PATH'), CMD_DATA_JSON_FILE) +# pylint: disable=C0301 class InteractiveCommand(object): + """ Class Interactive command""" def __init__(self, shell=None ): self.shell = shell - fp = open(pylxca_cmd_data, 'r') - self.command_data = json.load(fp) + filepointer = open(pylxca_cmd_data, 'r', encoding="utf8") + self.command_data = json.load(filepointer) def get_options(self): + """ get_options""" return {} def get_name(self): + """ get_name""" return self.__class__.__name__ - def get_help_option(self): + """ get_help_options""" return self.command_data[self.__class__.__name__].get('add_help', True) - def _process_epilog(self, str_list): epilog = "\r\n ".join(str_list) epilog = textwrap.dedent(epilog) return epilog - def _validate_combination(self, input_dict, valid_dict): ''' This function validate input combinations @@ -53,7 +58,7 @@ def _validate_combination(self, input_dict, valid_dict): valid_list = valid_dict[input_dict['subcmd']] else: valid_list = valid_dict['global'] - except Exception as e: + except Exception: raise Exception("Error in getting valid_list") # remove None and empty string and len zero lists @@ -61,7 +66,7 @@ def _validate_combination(self, input_dict, valid_dict): copy_input_dict = {} for k in input_dict.keys(): if k not in ['func', 'view','subcmd']: - if not (input_dict[k] == None or (isinstance(input_dict[k], list) and len(input_dict[k]) == 0)): + if not (input_dict[k] is None or (isinstance(input_dict[k], list) and len(input_dict[k]) == 0)): copy_input_dict[k] = input_dict[k] input_key_set = set(copy_input_dict.keys()) @@ -81,21 +86,25 @@ def _validate_combination(self, input_dict, valid_dict): return False, suggested_combination def get_additional_detail(self): + """ get_help_options""" epilog = self.command_data[self.__class__.__name__].get('additional_detail', []) return self._process_epilog(epilog) def get_short_desc(self): + """ get_short_desc""" return self.command_data[self.__class__.__name__]['description'] def post_parsing_validation(self, opts): + """ post_parsing_validation""" valid_combination = self.command_data[self.__class__.__name__].get('valid_combination', None) if valid_combination: valid, combination = self._validate_combination(opts, valid_combination) if not valid: - raise Exception("Invalid Missing Arguments %s" % str(combination)) + raise Exception (f"Invalid Missing Arguments {str(combination)}") def cmd1(self, args): + """ cmd1""" print('cmd1', args) def _preprocess_argparse_dict(self, cmd_dict): @@ -104,9 +113,10 @@ def _preprocess_argparse_dict(self, cmd_dict): if 'type' in cmd_dict: if cmd_dict['type'] in replace_with.keys(): cmd_dict['type'] = replace_with[cmd_dict['type']] - except Exception as err: - raise("Error while preprocessing argparse dict for type replacement") + except Exception: + raise Exception("Error while preprocessing argparse dict for type replacement") def get_argparse_options(self): + """ get_argparse_options""" parser = argparse.ArgumentParser(prog=self.get_name(), description=self.get_short_desc(), formatter_class=argparse.RawDescriptionHelpFormatter, epilog=self.get_additional_detail(), @@ -170,77 +180,77 @@ def get_argparse_options(self): return parser def invalid_input_err(self): + """ invalid_input_err""" self.sprint("Invalid Input ") self.sprint("for help type command -h") return - def sprint(self,str): - if self.shell: self.shell.sprint(str) - + """ sprint""" + if self.shell: + self.shell.sprint(str) def parse_args(self, args): + """ parse_args""" try: parser = self.get_argparse_options() namespace = parser.parse_args(args) opt_dict = vars(namespace) self.post_parsing_validation(opt_dict) - except argparse.ArgumentError as e: - raise(e) - except SystemExit as e: - raise(e) - except AttributeError as e: + except argparse.ArgumentError as argparseerror: + raise argparseerror + except SystemExit as systemexiterror: + raise systemexiterror + except AttributeError: #TODO move this some where extype, ex, tb = sys.exc_info() formatted = traceback.format_exception_only(extype, ex)[-1] - message = "Check getopt short and long options %s" % (formatted) + message = f"Check getopt short and long options {formatted}" raise RuntimeError(message, tb) return opt_dict def handle_no_input(self,con_obj): + """ parse_args""" #no_opt action can differ command to command so override this function if required obj = None try: - api = lxca_api() + api = LxcaApi() obj = api.api(self.get_name(), None,con_obj) except ConnectionError: self.sprint("Connection is not Initialized, Try connect") except RuntimeError: self.sprint("Session Error to LXCA, Try connect") - except Exception as err: - self.sprint("Exception occurred: %s" %(err)) + except Exception: + self.sprint("Exception occurred") return obj - def handle_input(self, dict_handler,con_obj = None): + """ handle_input""" obj = None - api = lxca_api() + api = LxcaApi() obj = api.api(self.get_name(),dict_handler,con_obj) return obj - def show_output(self, py_obj,view_filter = "default"): - + """ show_output""" ostream = sys.__stdout__ if self.shell: ostream = self.shell.ostream view = lxca_view.lxca_view(ostream) view.show_output(py_obj,self.get_name(),view_filter) return - def handle_output(self, py_obj): + """ handle_output""" return - def handle_command(self, opts, args): - + """ handle_command""" con_obj = None try: opts = self.parse_args(args) - except SystemExit as e: + except SystemExit: # ignore this as we need to continue on shell return out_obj = None - opt_dict = None + #opt_dict = None view_filter = "default" - try: if not opts: out_obj = self.handle_no_input(con_obj) @@ -250,7 +260,6 @@ def handle_command(self, opts, args): out_obj = self.handle_input(opts,con_obj) if opts: view_filter = next((item for item in [opts.get('v') , opts.get('view')] if item is not None),'default') - if out_obj: if isinstance(out_obj, dict): self.show_output(out_obj,view_filter) @@ -258,13 +267,6 @@ def handle_command(self, opts, args): self.handle_output(out_obj) except ConnectionError: self.sprint("Connection is not Initialized, Try connect") - except HTTPError as re: - self.sprint("Exception %s occurred while executing command."%(re.response.content)) - except ConnectionError as re: - self.sprint("Exception %s occurred while executing command."%(re.response.content)) except RuntimeError: self.sprint("Session Error to LXCA, Try connect") - except Exception as err: - self.sprint("Exception occurred: %s" %(err)) - return out_obj diff --git a/pylxca/pylxca_cmd/lxca_ishell.py b/pylxca/pylxca_cmd/lxca_ishell.py index 6506de0..4ada744 100644 --- a/pylxca/pylxca_cmd/lxca_ishell.py +++ b/pylxca/pylxca_cmd/lxca_ishell.py @@ -3,12 +3,12 @@ @author: Girish Kumar , Prashant Bhosale @license: Lenovo License @copyright: Copyright 2016, Lenovo -@organization: Lenovo -@summary: This module provides interactive shell class which provides base for interactive shell -feature and accepts raw input from command line +@organization: Lenovo +@summary: This module provides interactive shell class which provides base for interactive shell +feature and accepts raw input from command line ''' - -import re,sys,os,traceback +import sys +import os import itertools import logging import shlex @@ -17,18 +17,21 @@ from pylxca.pylxca_cmd import lxca_cmd from pylxca.pylxca_cmd.lxca_icommands import InteractiveCommand from pylxca.pylxca_cmd.lxca_view import lxca_ostream -from pylxca.pylxca_cmd import lxca_icommands +#from pylxca.pylxca_cmd import lxca_icommands #from rlcompleter import readline logger = logging.getLogger(__name__) +# pylint: disable=C0103 +# pylint: disable=C0301 +# pylint: disable=C0303 class InteractiveShell(object): - + """ Class Interactive shell """ class help(InteractiveCommand): """ Prints a list of available commands and their descriptions, or the help text of a specific command. Requires a list of the available commands in - order to display text for them. + order to display text for them. @ivar commands: A dictionary of available commands, bound to L{InteractiveShell.commands} @type commands: C{dict} @@ -58,7 +61,6 @@ def handle_command(self, opts, args): @return: Returns nothing, sends messages to stdout @rtype: None """ - if len(args) == 0: self.do_command_summary( ) return @@ -93,16 +95,16 @@ def do_command_summary(self): if name == 'help': continue try: - self.sprint(' %s %s' % (name.ljust(cmdwidth), + self.sprint(' %s %s' % (name.ljust(cmdwidth), command.get_short_desc( ))) - except: + except Exception: #For some commands there is no short desc so it will be skipped continue def get_short_desc(self): return '' - def get_help_message(self): + """ get help message""" return '' class exit(InteractiveCommand): @@ -115,12 +117,12 @@ def handle_command(self, opts, args): def get_short_desc(self): return 'Exit the program.' - def get_help_message(self): + """ get help message""" return 'Type exit and the program will exit. There are no options to this command' - def __init__(self, + def __init__(self, banner="Welcome to Interactive Shell", prompt=" >>> "): self.banner = banner @@ -129,7 +131,6 @@ def __init__(self, self.ostream = lxca_ostream() self.add_command(self.help(self.commands,self)) self.add_command(self.exit()) - self.add_command(lxca_cmd.connect(self)) self.add_command(lxca_cmd.disconnect(self)) self.add_command(lxca_cmd.log(self)) @@ -166,22 +167,23 @@ def __init__(self, self.add_command(lxca_cmd.license(self)) def set_ostream_to_null(self): - self.ostream = open(os.devnull, 'w') - + """ set_ostream_to_null""" + self.ostream = open(os.devnull, 'w', encoding="utf8") def sprint(self,str): + """ sprint""" if self.ostream: self.ostream.write(str) - def print_Hello(self): + """ print_Hello""" self.sprint("Hello") - def add_command(self, command): + """ add_command""" if command.get_name( ) in self.commands: - raise Exception('command %s already registered' % command.get_name( )) + raise Exception('command {%s} already registered', command.get_name( )) self.commands[command.get_name()] = command - def run(self): + """ run""" self.sprint('') self.sprint('-'*50) self.sprint(self.banner) @@ -189,7 +191,6 @@ def run(self): self.sprint('Use "lxca_shell --api" to enable Interactive Python LXCA Shell ') self.sprint('-'*50) self.sprint('') - while True: try: # readline.set_completer_delims(' \t\n;') @@ -204,10 +205,9 @@ def run(self): self.handle_input(command_line) continue - # TODO: Need to rename this function to handle_cli_params def handle_input(self, command_line): - + """ handle_input""" command_line = command_line.strip() # Get command @@ -225,7 +225,7 @@ def handle_input(self, command_line): if not command_name in self.commands: self.sprint('Unknown command: "%s". Type "help" for a list of commands.' % command_name) - return + return command = self.commands[command_name] @@ -237,16 +237,16 @@ def handle_input(self, command_line): re_args = shlex.split(command_args) #re_args = re.findall('\-\-\S+|\-\S+|\S+[\s*\w+]*', command_args) # Parse args if present - for i in range(0, len(re_args)): + for i in enumerate(len(re_args)): args.append( re_args[i] ) try: return command.handle_command(opts=opts, args=args) except Exception as err: - logger.error("Exception occurred while processing command %s " %str(err)) + logger.error("Exception occurred while processing command {%s} ",str(err)) return - # TODO: We should remove this, All API level code should give call to handle_input_dict rather def handle_input_args(self, command_name,*args, **kwargs): + """ handle_input_args""" # Show message when no command if not command_name: return @@ -259,7 +259,6 @@ def handle_input_args(self, command_name,*args, **kwargs): opts = {} args_dict = {} - for item in kwargs['kwargs']: args_dict['--' + item] = kwargs['kwargs'][item] @@ -271,9 +270,9 @@ def handle_input_args(self, command_name,*args, **kwargs): except Exception as err: self.sprint("Exception occurred while processing command.") raise err - - # TODO: We should rename this to handle_api_params + # We should rename this to handle_api_params def handle_input_dict(self, command_name,con, param_dict, use_argparse = True): + """ handle_input_dict""" # Show message when no command if not command_name: return @@ -298,9 +297,9 @@ def handle_input_dict(self, command_name,con, param_dict, use_argparse = True): args_list = args_list + list(itertools.chain(*list(args_dict.items()))) param_dict = command.parse_args(args_list) - except SystemExit as err: + except SystemExit: self.sprint("Exception occurred while parsing command.") - raise Exception("Invalid argument") + raise SystemExit("Invalid argument") except Exception as err: self.sprint("Exception occurred while parsing api input.") raise err @@ -312,28 +311,27 @@ def handle_input_dict(self, command_name,con, param_dict, use_argparse = True): raise err - """ - TODO: - def auto_complete(self, text, state): - command_list = self.commands.keys() - re_space = re.compile('.*\s+$', re.M) - "Generic readline completion entry point." - buffer = readline.get_line_buffer() - line = readline.get_line_buffer().split() - # show all commands - if not line: - return [c + ' ' for c in command_list][state] - # account for last argument ending in a space - if re_space.match(buffer): - line.append('') - # resolve command to the implementation function - cmd = line[0].strip() - if cmd in command_list: - impl = getattr(self, 'complete_%s' % cmd) - args = line[1:] - if args: - return (impl(args) + [None])[state] - return [cmd + ' '][state] - results = [c + ' ' for c in command_list if c.startswith(cmd)] + [None] - return results[state] - """ \ No newline at end of file + # """ + # TODO: def auto_complete(self, text, state): + # command_list = self.commands.keys() + # re_space = re.compile('.*\s+$', re.M) + # "Generic readline completion entry point." + # buffer = readline.get_line_buffer() + # line = readline.get_line_buffer().split() + # # show all commands + # if not line: + # return [c + ' ' for c in command_list][state] + # # account for last argument ending in a space + # if re_space.match(buffer): + # line.append('') + # # resolve command to the implementation function + # cmd = line[0].strip() + # if cmd in command_list: + # impl = getattr(self, 'complete_%s' % cmd) + # args = line[1:] + # if args: + # return (impl(args) + [None])[state] + # return [cmd + ' '][state] + # results = [c + ' ' for c in command_list if c.startswith(cmd)] + [None] + # return results[state] + # """ diff --git a/pylxca/pylxca_cmd/lxca_pyshell.py b/pylxca/pylxca_cmd/lxca_pyshell.py index ce0384a..028c7c7 100644 --- a/pylxca/pylxca_cmd/lxca_pyshell.py +++ b/pylxca/pylxca_cmd/lxca_pyshell.py @@ -90,7 +90,7 @@ def connect(*args, **kwargs): pw Password to Authenticate Lenovo XClarity Administrator noverify flag to indicate to not verify server certificate -@example +@example con1 = connect( url = "https://10.243.12.142",user = "USERID", pw = "Password", noverify = "True") ''' global SHELL_OBJ @@ -99,7 +99,7 @@ def connect(*args, **kwargs): if len(args) == 0 and len(kwargs) == 0: return - for i in range(len(args)): + for i in enumerate(len(args)): kwargs[keylist[i]] = args[i] con = SHELL_OBJ.handle_input_args(command_name, args=args, kwargs=kwargs) @@ -134,7 +134,7 @@ def disconnect(*args, **kwargs): con Connection Object to Lenovo XClarity Administrator -@example +@example disconnect() ''' global SHELL_OBJ @@ -162,7 +162,7 @@ def cmms(*args, **kwargs): @summary: Use this function to get CMMs information - run this function as + run this function as data_dictionary = cmms( key1 = 'val1', key2 = 'val2', ...) @@ -171,13 +171,13 @@ def cmms(*args, **kwargs): keylist = ['con', 'uuid', 'chassis'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator uuid cmm uuid - chassis chassis uuid + chassis chassis uuid -@example +@example cmm_list = cmms( con = con1, uuid = 'fc3058cadf8b11d48c9b9b1b1b1b1b57') ''' global SHELL_OBJ @@ -204,7 +204,7 @@ def chassis(*args, **kwargs): @summary: Use this function to get Chassis information - run this function as + run this function as data_dictionary = chassis( key1 = 'val1', key2 = 'val2', ...) @@ -213,14 +213,14 @@ def chassis(*args, **kwargs): keylist = ['con', 'uuid', 'status'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator uuid chassis uuid status chassis manage status (managed/unmanaged) -@example +@example chassis_list = chassis( con = con1, uuid = 'fc3058cadf8b11d48c9b9b1b1b1b1b57') ''' global SHELL_OBJ @@ -247,7 +247,7 @@ def fans(*args, **kwargs): @summary: Use this function to get fans information - run this function as + run this function as data_dictionary = fans( key1 = 'val1', key2 = 'val2', ...) @@ -256,13 +256,13 @@ def fans(*args, **kwargs): keylist = ['con', 'uuid', 'chassis'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator uuid uuid of fan chassis chassis uuid -@example +@example fans_list = fans( con = con1, uuid = 'fc3058cadf8b11d48c9b9b1b1b1b1b57') ''' global SHELL_OBJ @@ -289,7 +289,7 @@ def fanmuxes(*args, **kwargs): @summary: Use this function to get fanmuxes information - run this function as + run this function as data_dictionary = fanmuxes( key1 = 'val1', key2 = 'val2', ...) @@ -298,13 +298,13 @@ def fanmuxes(*args, **kwargs): keylist = ['con','uuid','chassis'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator uuid uuid of fanmux chassis chassis uuid -@example +@example ''' global SHELL_OBJ @@ -331,7 +331,7 @@ def nodes(*args, **kwargs): @summary: Use this function to get nodes information - run this function as + run this function as data_dictionary = nodes( key1 = 'val1', key2 = 'val2', ...) @@ -340,7 +340,7 @@ def nodes(*args, **kwargs): keylist = ['con','uuid','chassis','status', 'modify', 'metrics'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator uuid uuid of node @@ -349,10 +349,9 @@ def nodes(*args, **kwargs): modify JSON object of modifyable node properties metrics flag to fetch metrics of all nodes or metrics of a node belonging to the provided uuid -@example +@example nodes(uuid="FAA6E3D494E511E6A0739B91ED670CE8",modify='{"location":{"location": "new location", "rack": "rack 5","lowestRackUnit": 3}}') - ''' global SHELL_OBJ command_name = sys._getframe().f_code.co_name @@ -378,7 +377,7 @@ def switches(*args, **kwargs): @summary: Use this function to get switches information - run this function as + run this function as data_dictionary = switches( key1 = 'val1', key2 = 'val2', ...) @@ -387,7 +386,7 @@ def switches(*args, **kwargs): keylist = ['con','uuid','chassis','ports','action'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator uuid uuid of switch @@ -395,7 +394,7 @@ def switches(*args, **kwargs): ports empty ports string list all ports for uuid, comma separated ports action enable/disable ports -@example +@example ''' global SHELL_OBJ @@ -424,7 +423,7 @@ def powersupplies(*args, **kwargs): @summary: Use this function to get powersupplies information - run this function as + run this function as data_dictionary = powersupplies( key1 = 'val1', key2 = 'val2', ...) @@ -433,13 +432,13 @@ def powersupplies(*args, **kwargs): keylist = ['con','uuid','chassis'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator uuid uuid of power supply chassis chassis uuid -@example +@example ''' global SHELL_OBJ @@ -465,7 +464,7 @@ def scalablesystem(*args, **kwargs): @summary: Use this function to get scalablesystem information - run this function as + run this function as data_dictionary = scalablesystem( key1 = 'val1', key2 = 'val2', ...) @@ -474,13 +473,13 @@ def scalablesystem(*args, **kwargs): keylist = ['con','id','type'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator id scalable complex id type type (flex/rackserver) -@example +@example ''' global SHELL_OBJ @@ -508,7 +507,7 @@ def discover(*args, **kwargs): @summary: Use this function to discover endpoint from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = discover( key1 = 'val1', key2 = 'val2', ...) @@ -517,7 +516,7 @@ def discover(*args, **kwargs): keylist = ['con','ip','job'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator ip One or more IP addresses for each endpoint to be discovered. @@ -554,7 +553,7 @@ def manage(*args, **kwargs): @summary: Use this function to manage endpoint from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = manage( key1 = 'val1', key2 = 'val2', ...) @@ -563,7 +562,7 @@ def manage(*args, **kwargs): keylist = ['con','subcmd','ip','user','pw','rpw','job','force', 'storedcredential_id'] @param - The parameters for this command are as follows + The parameters for this command are as follows con Connection Object to Lenovo XClarity Administrator subcmd @@ -575,9 +574,9 @@ def manage(*args, **kwargs): job Job ID of existing manage request storedcredential_id Store Crendential Id to be used for device manage operation if this is provided user is not required - Note : mp, type and epuuid parameters are dedpriciated and only kept for backword compatibility. + Note : mp, type and epuuid parameters are dedpriciated and only kept for backword compatibility. -@example +@example jobid = manage(con=con1, subcmd='device', ip="10.243.6.68",user="USERID",pw="PASSW0RD",rpw="PASSW0RD") jobid = manage(con=con1, subcmd='device', ip="10.243.6.68",storedcredintail_id="12") @@ -626,7 +625,7 @@ def unmanage(*args, **kwargs): @summary: Use this function to unmanage endpoint from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = unmanage( key1 = 'val1', key2 = 'val2', ...) @@ -635,8 +634,8 @@ def unmanage(*args, **kwargs): keylist = ['con','subcmd','ep','force','job'] @param - The parameters for this command are as follows - subcmd device \ job_status + The parameters for this command are as follows + subcmd device job_status ep one or more endpoints to be unmanaged. This is comma separated list of multiple endpoints, each endpoint should contain endpoint information separated by semicolon. @@ -651,7 +650,7 @@ def unmanage(*args, **kwargs): force Indicates whether to force the unmanagement of an endpoint (True/False) job Job ID of unmanage request -@example +@example endpoint = '10.240.195.39;D31C76F0302503B50010D21DE03A0523;Rack-Tower' unmanage(con_lxca, subcmd='device', ep=endpoint) ''' @@ -681,7 +680,7 @@ def configpatterns(*args, **kwargs): Use this function to Retrieve information and deploy all server and category patterns that have been defined in the Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = configpatterns( key1 = 'val1', key2 = 'val2', ...) @@ -690,7 +689,7 @@ def configpatterns(*args, **kwargs): keylist = ['con','subcmd','id', 'includeSettings', 'endpoint','restart','type', pattern_update_dict, name, status] @param - The parameters for this command are as follows + The parameters for this command are as follows subcmd list, apply, import , status id The unique ID that was assigned when the server pattern was created name name of pattern , this is used for apply @@ -713,7 +712,7 @@ def configpatterns(*args, **kwargs): status check config status for given uuid in endpoint True -@example +@example list all configpatterns rep = configpatterns(con, subcmd = 'list') @@ -778,7 +777,7 @@ def configprofiles(*args, **kwargs): Use this function to Retrieve information server configuration profiles that have been defined in the Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = configprofiles( key1 = 'val1', key2 = 'val2', ...) @@ -787,7 +786,7 @@ def configprofiles(*args, **kwargs): keylist = ['con', 'subcmd', 'id', 'name', 'endpoint', 'restart', 'powerdown', 'resetimm', 'resetswitch', 'force'] @param - The parameters for this command are as follows + The parameters for this command are as follows subcmd list, rename, activate, unassign, delete id The unique ID that was assigned when the server profile was created name profile name @@ -831,15 +830,12 @@ def configprofiles(*args, **kwargs): return out_obj - return out_obj - - def configtargets(*args, **kwargs): ''' @summary: Use this function to get config pattern targets from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = configtargets( key1 = 'val1', key2 = 'val2', ...) @@ -848,10 +844,10 @@ def configtargets(*args, **kwargs): keylist = ['con','id'] @param - The parameters for this command are as follows + The parameters for this command are as follows id config target id -@example +@example ''' global SHELL_OBJ @@ -877,7 +873,7 @@ def updatepolicy(*args, **kwargs): @summary: Use this function to read Firmwar update Policy from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = updatepolicy( key1 = 'val1', key2 = 'val2', ...) @@ -886,7 +882,7 @@ def updatepolicy(*args, **kwargs): keylist = ['con', 'subcmd', 'info','job','uuid',policy','Type'] @param - The parameters for this command are as follows + The parameters for this command are as follows subcmd list,query, assign , status info Specifies the type of information to return. This can be one of the following values: FIRMWARE- Returns information about firmware that is applicable to each managed endpoint @@ -933,7 +929,7 @@ def updaterepo(*args, **kwargs): @summary: Use this function to get repository info from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = updaterepo( key1 = 'val1', key2 = 'val2', ...) @@ -942,7 +938,7 @@ def updaterepo(*args, **kwargs): keylist = ['con', 'subcmd', 'key', 'mt', 'scope', 'fixids', 'type'] @param - The parameters for this command are as follows + The parameters for this command are as follows subcmd The action to take. This can be one of the following values. @@ -969,7 +965,7 @@ def updaterepo(*args, **kwargs): scope scope of operation fixids comma separated fixids type filetype for PUT opertaion -@example +@example rep = updaterepo(con, "query", k="size") rep = updaterepo(con, subcmd = "read") rep = updaterepo(con_lxca, subcmd = "read") @@ -1110,7 +1106,7 @@ def users(*args, **kwargs): @summary: Use this function to get users data from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = users( key1 = 'val1', key2 = 'val2', ...) @@ -1119,11 +1115,11 @@ def users(*args, **kwargs): keylist = ['con','id'] @param - The parameters for this command are as follows + The parameters for this command are as follows id unique ID of the user to be retrieved -@example +@example ''' global SHELL_OBJ @@ -1149,10 +1145,10 @@ def ffdc(*args, **kwargs): ''' @summary: - Use this function to Collect and export specific endpoint data + Use this function to Collect and export specific endpoint data from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = ffdc( key1 = 'val1', key2 = 'val2', ...) @@ -1161,7 +1157,7 @@ def ffdc(*args, **kwargs): keylist = ['con','uuid'] @param - The parameters for this command are as follows + The parameters for this command are as follows uuid UUID of the target endpoint this is manadatory parameter @@ -1241,7 +1237,7 @@ def lxcalog(*args, **kwargs): @summary: Use this function to get Lenovo XClarity Administrator LOG information - run this function as + run this function as data_dictionary = lxcalog( key1 = 'val1', key2 = 'val2', ...) @@ -1250,11 +1246,11 @@ def lxcalog(*args, **kwargs): keylist = ['con','filter'] @param - The parameters for this command are as follows + The parameters for this command are as follows filter filter for the event -@example +@example ''' global SHELL_OBJ @@ -1282,7 +1278,7 @@ def jobs(*args, **kwargs): @summary: Use this function to get jobs information from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = jobs( key1 = 'val1', key2 = 'val2', ...) @@ -1291,7 +1287,7 @@ def jobs(*args, **kwargs): keylist = ['con','id','uuid','state','cancel','delete'] @param - The parameters for this command are as follows + The parameters for this command are as follows id= job id uuid= uuid of endpoint for which jobs should be retrieved @@ -1308,7 +1304,7 @@ def jobs(*args, **kwargs): cancel= cancel job of specified id delete= delete job of specified id -@example +@example ''' global SHELL_OBJ @@ -1337,7 +1333,7 @@ def manifests(*args, **kwargs): @summary: Use this function to send solution manifest to and retreive manifests from Lenovo XClarity Administrator - run this function as + run this function as data_dictionary = manifests( conn_handle, input_args_dictionary{key,value} ) @@ -1346,12 +1342,12 @@ def manifests(*args, **kwargs): keylist = [id','file'] @param - The parameters for this command are as follows + The parameters for this command are as follows id= solution id file= path to manifest file -@example +@example ''' global SHELL_OBJ @@ -1443,7 +1439,7 @@ def resourcegroups(*args, **kwargs): @param The parameters for this command are as follows - uuid= UUID of already created Group + uuid= UUID of already created Group name= Name of Resource Group desc= Description of Resource Group type= Type of Resource Group. <{"static", "dynamic", "solution"}>, @@ -1524,7 +1520,7 @@ def resourcegroups(*args, **kwargs): con = _validate_param(keylist, long_short_key_map, mandatory_options_list, optional_keylist, mutually_exclusive_keys, param_dict, *args, **kwargs) - LOGGER.debug("resourcegroups %s" %str(param_dict)) + LOGGER.debug("resourcegroups {{%s}}",str(param_dict)) if 'type' in param_dict: if 'solution' in param_dict['type']: out_obj = SHELL_OBJ.handle_input_dict(command_name, con, param_dict, False) @@ -1554,7 +1550,7 @@ def _validate_param(keylist, long_short_key_map, mandatory_options_list, optiona con = None for key in keylist: short_key = long_short_key_map.get(key) - if (key in list(kwargs.keys())): + if key in list(kwargs.keys()): param_dict[key] = kwargs[key] elif key in param_dict: continue @@ -1563,11 +1559,10 @@ def _validate_param(keylist, long_short_key_map, mandatory_options_list, optiona elif len(arglist) >= 1: value = arglist.pop() - if value != None: + if value is not None: param_dict[key] = value elif key not in optional_keylist: - LOGGER.error(" Invalid Input args %s is not in optional list %s" % ( - key, str(mandatory_options_list))) + LOGGER.error(" Invalid Input args {%s} is not in optional list {%s}",key, str(mandatory_options_list)) raise ValueError("Invalid Input Arguments") if key == 'con': @@ -1582,21 +1577,21 @@ def _validate_param(keylist, long_short_key_map, mandatory_options_list, optiona # Checking mandatory option_list presence if me_key in list(mandatory_options_list.keys()): if not set(mandatory_options_list[me_key]).issubset(set(param_dict.keys())): - LOGGER.error(" Invalid command invocation %s of mandatory list %s is not in arguments parovided" % ( - me_key, str(mandatory_options_list))) + LOGGER.error(" Invalid command invocation {%s} of mandatory list {%s} is not in arguments parovided", + me_key, str(mandatory_options_list)) raise AttributeError("Invalid command invocation") # Checking mutually exclusive key presense if me_key in mutually_exclusive_keys: if me_key_found: - LOGGER.error(" Invalid command invocation %s of mutual exclusive list %s " % ( - me_key, str(mutually_exclusive_keys))) + LOGGER.error(" Invalid command invocation {%s} of mutual exclusive list {%s} ", + me_key, str(mutually_exclusive_keys)) raise AttributeError("Invalid command invocation") me_key_found = True if not set(keylist + list(long_short_key_map.values())).issuperset(set(kwargs.keys())): - LOGGER.error(" Invalid Input args: %s unsupported argument passed" - % list(set(kwargs.keys()).difference(set(keylist + long_short_key_map.values())))) + LOGGER.error(" Invalid Input args: {%s} unsupported argument passed", + list(set(kwargs.keys()).difference(set(keylist + long_short_key_map.values())))) raise ValueError("Invalid Input Arguments") return con @@ -2005,7 +2000,7 @@ def license(*args, **kwargs): con Connection Object to Lenovo XClarity Administrator -@example +@example license(con) ''' global SHELL_OBJ @@ -2026,4 +2021,3 @@ def license(*args, **kwargs): out_obj = SHELL_OBJ.handle_input_dict(command_name, con, param_dict, False) return out_obj - diff --git a/pylxca/pylxca_cmd/lxca_view.py b/pylxca/pylxca_cmd/lxca_view.py index 2da9b81..21b63e2 100644 --- a/pylxca/pylxca_cmd/lxca_view.py +++ b/pylxca/pylxca_cmd/lxca_view.py @@ -8,62 +8,74 @@ data and displays on ostream. ''' -import json, re, os, sys, logging -from pprint import pprint +import os +import sys +import logging +#from pprint import pprint import xml.etree.cElementTree as ElementTree -import pylxca.pylxca_cmd +#import pylxca.pylxca_cmd -filter_file = "lxca_filters.xml" -output_file = "lxca_console.out" -pylxca_filter = os.path.join(os.getenv('PYLXCA_CMD_PATH'), filter_file) -pylxca_outfile = os.path.join(os.getenv('PYLXCA_CMD_PATH'), output_file) +FILTER_FILE = "lxca_filters.xml" +OUTPUT_FILE = "lxca_console.out" +pylxca_filter = os.path.join(os.getenv('PYLXCA_CMD_PATH'), FILTER_FILE) +pylxca_outfile = os.path.join(os.getenv('PYLXCA_CMD_PATH'), OUTPUT_FILE) -indent = 0 +INDENT = 0 logger = logging.getLogger(__name__) - +# pylint: disable=R0205 class Tee(object): + """ Class Tee""" def __init__(self, *files): self.files = files def write(self, obj): - for f in self.files: - f.write(obj) - f.flush() # If you want the output to be visible immediately + """ Class Tee write()""" + for file in self.files: + file.write(obj) + file.flush() # If you want the output to be visible immediately def flush(self) : - for f in self.files: - f.flush() - + """ Class Tee flush()""" + for file in self.files: + file.flush() +# pylint: disable=C0103 +# pylint: disable=R0205 class lxca_ostream(object): + """ Class lxca_ostream""" def __init__(self): self.stdout = sys.__stdout__ self.print_lvl = 1 def get_lvl(self): + """ Class lxca_ostream get_lvl()""" return self.print_lvl def set_lvl(self,lvl): + """ Class lxca_ostream set_lvl()""" self.print_lvl = lvl try: if lvl == 0: - self.stdout = open(os.devnull, 'w') + self.stdout = open(os.devnull, 'w', encoding="utf8") elif lvl == 1: self.stdout = sys.__stdout__ elif lvl == 2: - self.stdout = open(pylxca_outfile, 'w') + self.stdout = open(pylxca_outfile, 'w', encoding="utf8") elif lvl == 3: - outfile = open(pylxca_outfile, 'w') - self.stdout = Tee(sys.__stdout__, outfile) - except Exception as e: + with open(pylxca_outfile, 'w', encoding="utf8") as outfile: + self.stdout = Tee(sys.__stdout__, outfile) + except Exception: return False return True def write(self, string): + """ Class lxca_ostream write()""" sys.stdout = self.stdout print(string) sys.stdout = sys.__stdout__ - +# pylint: disable=C0103 +# pylint: disable=R0205 class lxca_view(object): + """ Class lxca_view""" def __init__(self,ostream = sys.__stdout__): self.ostream = ostream @@ -80,35 +92,36 @@ def __init__(self,ostream = sys.__stdout__): def get_val(self,py_obj, tag ): + """ Class lxca_view get_val()""" a = [] try: if isinstance(py_obj, (dict)): - return(py_obj[tag]) + return py_obj[tag] if isinstance(py_obj, (list)): - - for i in range(0, len(py_obj)): + for i in enumerate(len(py_obj)): a.append(py_obj[i][tag]) - except: + except Exception: return None return a def get_view_filter(self, cmd_name, filter_tag): + """ Class lxca_view get_view_filter() """ vf_tree = ElementTree.parse(pylxca_filter) vf_root = vf_tree.getroot() - for vf in vf_root.findall(cmd_name): - if vf.attrib['name']==filter_tag: - return vf + for viewfilter in vf_root.findall(cmd_name): + if viewfilter.attrib['name']==filter_tag: + return viewfilter def print_recur(self,py_obj,view_filter): """Recursively prints the python object content as per view filter""" - global indent + global INDENT if str(view_filter.attrib.get('type')) != "object" : - self.ostream.write(' '*indent + '%s: %s' % (view_filter.tag.title(), self.get_val(py_obj,view_filter.attrib.get('name', view_filter.text)))) + self.ostream.write(' '*INDENT + '%s: %s' % (view_filter.tag.title(), self.get_val(py_obj,view_filter.attrib.get('name', view_filter.text)))) #else: # self.ostream.write('%s: ' % (view_filter.tag.title())) - indent += 4 + INDENT += 4 # View Filter has children so py_obj_item = self.get_val(py_obj, view_filter.attrib.get('name', view_filter.text)) #if py_obj_item is list then iterate through the list and call print recur for each @@ -119,22 +132,24 @@ def print_recur(self,py_obj,view_filter): else: for elem in view_filter.getchildren(): self.print_recur(py_obj_item,elem) - indent -= 4 + INDENT -= 4 - def print_cmd_resp_object(self,cmd_resp_item, vf): - for vf_elem in vf.getchildren(): + def print_cmd_resp_object(self,cmd_resp_item, viewfilter): + """ Class lxca_view print_cmd_resp_object() """ + for vf_elem in viewfilter.getchildren(): self.print_recur(cmd_resp_item,vf_elem) def show_output(self,cmd_reponse, cmd_name,filter_tag): - vf = self.get_view_filter(cmd_name,filter_tag) + """ Class lxca_view show_output() """ + viewfilter = self.get_view_filter(cmd_name,filter_tag) self.ostream.write("Printing "+ cmd_name + " Output:"+ "\n") if len(list(cmd_reponse.keys())) == 0: self.ostream.write("No "+ filter_tag + " returned."+ "\n") elif len(list(cmd_reponse.keys())) > 1: - self.print_cmd_resp_object(cmd_reponse, vf) + self.print_cmd_resp_object(cmd_reponse, viewfilter) else: for cmd_resp_item in cmd_reponse[list(cmd_reponse.keys())[0]]: - self.print_cmd_resp_object(cmd_resp_item, vf) - self.ostream.write('\n-----------------------------------------------------') \ No newline at end of file + self.print_cmd_resp_object(cmd_resp_item, viewfilter) + self.ostream.write('\n-----------------------------------------------------') diff --git a/setup.py b/setup.py index 46bc36e..dc9ff04 100755 --- a/setup.py +++ b/setup.py @@ -6,18 +6,20 @@ @organization: Lenovo @summary: Setup Script for PYLXCA ''' -import os, sys, re +import os +import sys +import re from codecs import open try: - from setuptools import setup, find_packages + from setuptools import setup except ImportError: print ("setuptools is needed to run this file") print ("Try -- 'sudo pip install setuptools'") print ("Exiting ..") sys.exit(1) - def read(fname): + """Open and read a file """ return open(os.path.join(os.path.dirname(__file__), fname)).read() with open('pylxca/__init__.py', 'r') as fd: