diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py index df88fa24e4a..2c027c36879 100644 --- a/tools/marvin/marvin/cloudstackConnection.py +++ b/tools/marvin/marvin/cloudstackConnection.py @@ -61,9 +61,11 @@ class cloudConnection(object): % (self.protocol, self.mgtSvr, self.port, self.path) def __copy__(self): - return cloudConnection(self.mgtSvr, self.port, self.user, self.passwd, - self.apiKey, self.securityKey, - self.asyncTimeout, self.logging, self.protocol, + return cloudConnection(self.mgtSvr, self.port, self.user, + self.passwd, self.apiKey, + self.securityKey, + self.asyncTimeout, self.logging, + self.protocol, self.path) def loglevel(self, lvl=logging.WARNING): @@ -85,7 +87,7 @@ class cloudConnection(object): timeout = self.asyncTimeout while timeout > 0: - asyncResonse = self.marvin_request(cmd, response_type=response) + asyncResonse = self.marvinRequest(cmd, response_type=response) if asyncResonse.jobstatus == 2: raise cloudstackException.cloudstackAPIException( @@ -144,14 +146,17 @@ class cloudConnection(object): payload["signature"] = signature try: - #https_flag : whether https enabled or not - #cert_path : ca and cert paths of the https connection + #https_flag : Signifies whether to verify connection over \ + #http or https, \ + #initialized to False, will be set to true if user provided https + #connection https_flag = False cert_path = () if self.protocol == "https": https_flag = True if self.certCAPath != "NA" and self.certPath != "NA": cert_path = (self.certCAPath, self.certPath) + #Verify whether protocol is "http", then call the request over http if self.protocol == "http": if method == 'POST': @@ -161,12 +166,15 @@ class cloudConnection(object): response = requests.get(self.baseurl, params=payload, verify=https_flag) else: - exception_check = False - exception_info = None - #use user provided CA certs for request + ''' + If protocol is https, then create the connection url with \ + user provided certificates \ + provided as part of cert + ''' try: if method == 'POST': - response = requests.post(self.baseurl, params=payload, + response = requests.post(self.baseurl, + params=payload, cert=cert_path, verify=https_flag) else: @@ -174,37 +182,42 @@ class cloudConnection(object): cert=cert_path, verify=https_flag) except Exception, e: - # attempt a connection using default certs - self.logging.debug("connection failed using provided certs" - " because of %s" % e) - exception_check = True - exception_info = e + ''' + If an exception occurs with user provided CA certs, \ + then try with default certs, \ + we dont need to mention here the cert path + ''' + self.logging.debug("Creating CS connection over https \ + didnt worked with user provided certs \ + , so trying with no certs %s" % e) if method == 'POST': - response = requests.post(self.baseurl, params=payload, + response = requests.post(self.baseurl, + params=payload, verify=https_flag) else: - response = requests.get(self.baseurl, params=payload, + response = requests.get(self.baseurl, + params=payload, verify=https_flag) - finally: - if exception_check and exception_info is not None: - raise exception_info except ConnectionError, c: - self.logging.debug("Connection refused." - " Reason: %s : %s" % (self.baseurl, c)) + self.logging.debug("Connection refused. Reason: %s : %s" + % (self.baseurl, c)) raise c except HTTPError, h: - self.logging.debug("Server returned error code: %s" % h) + self.logging.debug("Http Error.Server returned error code: %s" % h) raise h except Timeout, t: self.logging.debug("Connection timed out with %s" % t) raise t except RequestException, r: - self.logging.debug("Error returned by server %s" % r) + self.logging.debug("RequestException from server %s" % r) raise r + except Exception, e: + self.logging.debug("Error returned by server %s" % r) + raise e else: return response - def sanitize_command(self, cmd): + def sanitizeCommand(self, cmd): """ Removes None values, Validates all required params are present @param cmd: Cmd object eg: createPhysicalNetwork @@ -242,9 +255,9 @@ class cloudConnection(object): for k, v in val.iteritems(): requests["%s[%d].%s" % (param, i, k)] = v i = i + 1 - return cmdname, isAsync, requests + return cmdname.strip(), isAsync, requests - def marvin_request(self, cmd, response_type=None, method='GET', data=''): + def marvinRequest(self, cmd, response_type=None, method='GET', data=''): """ Requester for marvin command objects @param cmd: marvin's command from cloudstackAPI @@ -252,11 +265,13 @@ class cloudConnection(object): @param method: HTTP GET/POST, defaults to GET @return: """ - cmdname, isAsync, payload = self.sanitize_command(cmd) + cmdname, isAsync, payload = self.sanitizeCommand(cmd) self.logging.debug("sending %s request: %s %s" % (method, cmdname, str(payload))) - response = self.request( - cmdname, self.auth, payload=payload, method=method) + response = self.request(cmdname, + self.auth, + payload=payload, + method=method) self.logging.debug("Request: %s Response: %s" % (response.url, response.text)) try: diff --git a/tools/marvin/marvin/cloudstackTestClient.py b/tools/marvin/marvin/cloudstackTestClient.py index 5dcd8bf0f59..fbd4abab992 100644 --- a/tools/marvin/marvin/cloudstackTestClient.py +++ b/tools/marvin/marvin/cloudstackTestClient.py @@ -23,18 +23,35 @@ import random import string import hashlib +''' +@Desc : CloudStackTestClient is encapsulated class for getting various \ + clients viz., apiclient,dbconnection etc +@Input : mgmtDetails : Management Server Details + dbSvrDetails: Database Server details of Management \ + Server. Retrieved from configuration file. + asyncTimeout : + defaultWorkerThreads : + logging : +''' + class cloudstackTestClient(object): - def __init__(self, mgmtDetails, asyncTimeout=3600, - defaultWorkerThreads=10, logging=None): + def __init__(self, mgmtDetails, + dbSvrDetails, asyncTimeout=3600, + defaultWorkerThreads=10, + logging=None): self.connection = \ - cloudstackConnection.cloudConnection(mgmtDetails, asyncTimeout, + cloudstackConnection.cloudConnection(mgmtDetails, + asyncTimeout, logging) self.apiClient =\ cloudstackAPIClient.CloudStackAPIClient(self.connection) self.dbConnection = None + if dbSvrDetails is not None: + self.createDbConnection(dbSvrDetails.dbSvr, dbSvrDetails.port, + dbSvrDetails.user, + dbSvrDetails.passwd, dbSvrDetails.db) self.asyncJobMgr = None - self.ssh = None self.id = None self.defaultWorkerThreads = defaultWorkerThreads @@ -46,10 +63,10 @@ class cloudstackTestClient(object): def identifier(self, id): self.id = id - def dbConfigure(self, host="localhost", port=3306, user='cloud', - passwd='cloud', db='cloud'): - self.dbConnection = dbConnection.dbConnection(host, port, - user, passwd, db) + def createDbConnection(self, host="localhost", port=3306, user='cloud', + passwd='cloud', db='cloud'): + self.dbConnection = dbConnection.dbConnection(host, port, user, + passwd, db) def isAdminContext(self): """ @@ -69,13 +86,6 @@ class cloudstackTestClient(object): except: return 0 # user - def random_gen(self, size=6, chars=string.ascii_uppercase + string.digits): - """Generate Random Strings of variable length""" - randomstr = ''.join(random.choice(chars) for x in range(size)) - if self.identifier: - return ''.join([self.identifier, '-', randomstr]) - return randomstr - def createUserApiClient(self, UserName, DomainName, acctType=0): if not self.isAdminContext(): return self.apiClient @@ -147,17 +157,6 @@ class cloudstackTestClient(object): def getDbConnection(self): return self.dbConnection - def executeSql(self, sql=None): - if sql is None or self.dbConnection is None: - return None - - return self.dbConnection.execute() - - def executeSqlFromFile(self, sqlFile=None): - if sqlFile is None or self.dbConnection is None: - return None - return self.dbConnection.executeSqlFromFile(sqlFile) - def getApiClient(self): self.apiClient.id = self.identifier return self.apiClient diff --git a/tools/marvin/marvin/codegenerator.py b/tools/marvin/marvin/codegenerator.py index 96729f6bbfe..e0f056f66a0 100644 --- a/tools/marvin/marvin/codegenerator.py +++ b/tools/marvin/marvin/codegenerator.py @@ -222,7 +222,7 @@ class codeGenerator(object): body += self.space + self.space body += 'response = %sResponse()\n' % cmdName body += self.space + self.space - body += 'response = self.connection.marvin_request(command,' + body += 'response = self.connection.marvinRequest(command,' body += ' response_type=response, method=method)\n' body += self.space + self.space + 'return response\n' body += self.newline diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index 45c3d69ff14..50614c124c1 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -27,8 +27,8 @@ class managementServer(object): self.port = 8096 self.apiKey = None self.securityKey = None - self.certCAPath = None self.useHttps = None + self.certCAPath = None self.certPath = None diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index 6b5f64b8300..f2dccdbc53c 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -32,8 +32,12 @@ class deployDataCenters(object): if not path.exists(cfgFile) \ and not path.exists(path.abspath(cfgFile)): raise IOError("config file %s not found. please \ - specify a valid config file" % cfgFile) + specify a valid config file" % cfgFile) self.configFile = cfgFile + ''' + parsed configuration information + ''' + self.config = None def addHosts(self, hosts, zoneId, podId, clusterId, hypervisor): if hosts is None: @@ -515,7 +519,10 @@ class deployDataCenters(object): raise cloudstackException.InvalidParameterException( "Failed to load config %s" % self.configFile) + ''' Retrieving Management Server Connection Details ''' mgtDetails = self.config.mgtSvr[0] + ''' Retrieving Database Connection Details''' + dbSvrDetails = self.config.dbSvr loggers = self.config.logger testClientLogFile = None self.testCaseLogFile = None @@ -541,20 +548,20 @@ class deployDataCenters(object): self.testClientLogger = testClientLogger self.testClient = \ - cloudstackTestClient.cloudstackTestClient( - mgtDetails, logging=self.testClientLogger) + cloudstackTestClient.\ + cloudstackTestClient(mgtDetails, + dbSvrDetails, + logging=self.testClientLogger) if mgtDetails.apiKey is None: mgtDetails.apiKey, mgtDetails.securityKey = self.registerApiKey() mgtDetails.port = 8080 - self.testClient = cloudstackTestClient.cloudstackTestClient( - mgtDetails, logging=self.testClientLogger) - - """config database""" - dbSvr = self.config.dbSvr - if dbSvr is not None: - self.testClient.dbConfigure( - dbSvr.dbSvr, dbSvr.port, dbSvr.user, dbSvr.passwd, dbSvr.db) + self.testClient = \ + cloudstackTestClient.cloudstackTestClient( + mgtDetails, + dbSvrDetails, + logging= + self.testClientLogger) self.apiClient = self.testClient.getApiClient() """set hypervisor""" @@ -592,16 +599,13 @@ class deployDataCenters(object): self.configureS3(self.config.s3) if __name__ == "__main__": - parser = OptionParser() - parser.add_option("-i", "--input", action="store", default="./datacenterCfg", dest="input", help="the path \ where the json config file generated, by default is \ ./datacenterCfg") (options, args) = parser.parse_args() - deploy = deployDataCenters(options.input) deploy.deploy()