Multiple fixes to marvin framework

1. adding hypervisor information to configs
    TODO: support for multi-hypervisor zones?
2. CLOUDSTACK-601: Marvin unicode decode errors when running mysql
queries via dbClient
3. adding keypair support for remotessh client

Signed-off-by: Prasanna Santhanam <tsp@apache.org>
This commit is contained in:
Ashutosh Kelkar 2013-04-24 15:03:10 +05:30 committed by Prasanna Santhanam
parent f429c6687b
commit 2f40a90c53
8 changed files with 669 additions and 119 deletions

View File

@ -28,6 +28,8 @@ class job(object):
def __init__(self):
self.id = None
self.cmd = None
class jobStatus(object):
def __init__(self):
self.result = None
@ -37,8 +39,11 @@ class jobStatus(object):
self.duration = None
self.jobId = None
self.responsecls = None
def __str__(self):
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems()))
class workThread(threading.Thread):
def __init__(self, in_queue, outqueue, apiClient, db=None, lock=None):
threading.Thread.__init__(self)
@ -47,11 +52,11 @@ class workThread(threading.Thread):
self.connection = apiClient.connection.__copy__()
self.db = None
self.lock = lock
def queryAsynJob(self, job):
if job.jobId is None:
return job
try:
self.lock.acquire()
result = self.connection.poll(job.jobId, job.responsecls).jobresult
@ -59,10 +64,10 @@ class workThread(threading.Thread):
result = str(e)
finally:
self.lock.release()
job.result = result
return job
def executeCmd(self, job):
cmd = job.cmd
@ -70,14 +75,15 @@ class workThread(threading.Thread):
jobId = None
try:
self.lock.acquire()
if cmd.isAsync == "false":
jobstatus.startTime = datetime.datetime.now()
result = self.connection.make_request(cmd)
jobstatus.result = result
jobstatus.endTime = datetime.datetime.now()
jobstatus.duration = time.mktime(jobstatus.endTime.timetuple()) - time.mktime(jobstatus.startTime.timetuple())
jobstatus.duration = time.mktime(jobstatus.endTime.timetuple()) - time.mktime(
jobstatus.startTime.timetuple())
else:
result = self.connection.make_request(cmd, None, True)
if result is None:
@ -99,9 +105,9 @@ class workThread(threading.Thread):
jobstatus.result = sys.exc_info()
finally:
self.lock.release()
return jobstatus
def run(self):
while self.inqueue.qsize() > 0:
job = self.inqueue.get()
@ -109,18 +115,20 @@ class workThread(threading.Thread):
jobstatus = self.queryAsynJob(job)
else:
jobstatus = self.executeCmd(job)
self.output.put(jobstatus)
self.inqueue.task_done()
'''release the resource'''
self.connection.close()
class jobThread(threading.Thread):
def __init__(self, inqueue, interval):
threading.Thread.__init__(self)
self.inqueue = inqueue
self.interval = interval
def run(self):
while self.inqueue.qsize() > 0:
job = self.inqueue.get()
@ -130,23 +138,25 @@ class jobThread(threading.Thread):
job.apiClient.connection.close()
except:
pass
self.inqueue.task_done()
time.sleep(self.interval)
class outputDict(object):
def __init__(self):
self.lock = threading.Condition()
self.dict = {}
self.dict = {}
class asyncJobMgr(object):
def __init__(self, apiClient, db):
self.inqueue = Queue.Queue()
self.output = outputDict()
self.output = outputDict()
self.outqueue = Queue.Queue()
self.apiClient = apiClient
self.db = db
def submitCmds(self, cmds):
if not self.inqueue.empty():
return False
@ -160,11 +170,12 @@ class asyncJobMgr(object):
id += 1
ids.append(id)
return ids
def updateTimeStamp(self, jobstatus):
jobId = jobstatus.jobId
if jobId is not None and self.db is not None:
result = self.db.execute("select job_status, created, last_updated from async_job where id=%s"%jobId)
result = self.db.execute(
"select job_status, created, last_updated from async_job where id='%s'" % str(jobId))
if result is not None and len(result) > 0:
if result[0][0] == 1:
jobstatus.status = True
@ -174,7 +185,7 @@ class asyncJobMgr(object):
jobstatus.endTime = result[0][2]
delta = jobstatus.endTime - jobstatus.startTime
jobstatus.duration = delta.total_seconds()
def waitForComplete(self, workers=10):
self.inqueue.join()
lock = threading.Lock()
@ -183,28 +194,30 @@ class asyncJobMgr(object):
for i in range(workers):
worker = workThread(self.outqueue, resultQueue, self.apiClient, self.db, lock)
worker.start()
self.outqueue.join()
asyncJobResult = []
while resultQueue.qsize() > 0:
jobstatus = resultQueue.get()
self.updateTimeStamp(jobstatus)
asyncJobResult.append(jobstatus)
return asyncJobResult
'''put commands into a queue at first, then start workers numbers threads to execute this commands'''
def submitCmdsAndWait(self, cmds, workers=10):
self.submitCmds(cmds)
lock = threading.Lock()
for i in range(workers):
worker = workThread(self.inqueue, self.outqueue, self.apiClient, self.db, lock)
worker.start()
return self.waitForComplete(workers)
'''submit one job and execute the same job ntimes, with nums_threads of threads'''
def submitJobExecuteNtimes(self, job, ntimes=1, nums_threads=1, interval=1):
inqueue1 = Queue.Queue()
lock = threading.Condition()
@ -213,22 +226,23 @@ class asyncJobMgr(object):
setattr(newjob, "apiClient", copy.copy(self.apiClient))
setattr(newjob, "lock", lock)
inqueue1.put(newjob)
for i in range(nums_threads):
work = jobThread(inqueue1, interval)
work.start()
inqueue1.join()
'''submit n jobs, execute them with nums_threads of threads'''
def submitJobs(self, jobs, nums_threads=1, interval=1):
inqueue1 = Queue.Queue()
lock = threading.Condition()
for job in jobs:
setattr(job, "apiClient", copy.copy(self.apiClient))
setattr(job, "lock", lock)
inqueue1.put(job)
for i in range(nums_threads):
work = jobThread(inqueue1, interval)
work.start()

View File

@ -33,13 +33,18 @@ from requests import RequestException
class cloudConnection(object):
""" Connections to make API calls to the cloudstack management server
"""
def __init__(self, mgtSvr, port=8096, apiKey=None, securityKey=None,
def __init__(self, mgtSvr, port=8096, user=None, passwd=None,
apiKey=None, securityKey=None,
asyncTimeout=3600, logging=None, scheme='http',
path='client/api'):
self.apiKey = apiKey
self.securityKey = securityKey
self.mgtSvr = mgtSvr
self.port = port
if user:
self.user = user
if passwd:
self.passwd = passwd
self.logging = logging
self.path = path
self.retries = 5
@ -55,9 +60,10 @@ class cloudConnection(object):
% (self.protocol, self.mgtSvr, self.port, self.path)
def __copy__(self):
return cloudConnection(self.mgtSvr, self.port, self.apiKey,
self.securityKey, self.asyncTimeout,
self.logging, self.protocol, self.path)
return cloudConnection(self.mgtSvr, self.port, self.user, self.passwd,
self.apiKey, self.securityKey,
self.asyncTimeout, self.logging, self.protocol,
self.path)
def poll(self, jobid, response):
"""
@ -200,7 +206,8 @@ class cloudConnection(object):
@return:
"""
cmdname, isAsync, payload = self.sanitize_command(cmd)
self.logging.debug("sending %s request: %s %s" % (method, cmdname, str(payload)))
self.logging.debug("sending %s request: %s %s" % (method, cmdname,
str(payload)))
response = self.request(
cmdname, self.auth, payload=payload, method=method)
self.logging.debug("Request: %s Response: %s" %

View File

@ -18,24 +18,29 @@
import cloudstackConnection
import asyncJobMgr
import dbConnection
from cloudstackAPI import *
from cloudstackAPI import *
import random
import string
import hashlib
class cloudstackTestClient(object):
def __init__(self, mgtSvr=None, port=8096, apiKey = None, securityKey = None, asyncTimeout=3600,
def __init__(self, mgtSvr=None, port=8096, user=None, passwd=None,
apiKey=None, securityKey=None, asyncTimeout=3600,
defaultWorkerThreads=10, logging=None):
self.connection = cloudstackConnection.cloudConnection(mgtSvr, port, apiKey, securityKey, asyncTimeout, logging)
self.connection = \
cloudstackConnection.cloudConnection(
mgtSvr, port, user,
passwd, apiKey, securityKey,
asyncTimeout, logging)
self.apiClient = cloudstackAPIClient.CloudStackAPIClient(self.connection)
self.dbConnection = None
self.asyncJobMgr = None
self.ssh = None
self.defaultWorkerThreads = defaultWorkerThreads
def dbConfigure(self, host="localhost", port=3306, user='cloud', passwd='cloud', db='cloud'):
self.dbConnection = dbConnection.dbConnection(host, port, user, passwd, db)
def isAdminContext(self):
"""
A user is a regular user if he fails to listDomains;
@ -53,7 +58,7 @@ class cloudstackTestClient(object):
return 2 #domain-admin
except:
return 0 #user
def random_gen(self, size=6, chars=string.ascii_uppercase + string.digits):
"""Generate Random Strings of variable length"""
return ''.join(random.choice(chars) for x in range(size))
@ -61,7 +66,7 @@ class cloudstackTestClient(object):
def createUserApiClient(self, UserName, DomainName, acctType=0):
if not self.isAdminContext():
return self.apiClient
listDomain = listDomains.listDomainsCmd()
listDomain.listall = True
listDomain.name = DomainName
@ -73,11 +78,11 @@ class cloudstackTestClient(object):
cdomain.name = DomainName
domain = self.apiClient.createDomain(cdomain)
domId = domain.id
mdf = hashlib.md5()
mdf.update("password")
mdf_pass = mdf.hexdigest()
cmd = listAccounts.listAccountsCmd()
cmd.name = UserName
cmd.domainid = domId
@ -95,46 +100,47 @@ class cloudstackTestClient(object):
createAcctCmd.username = UserName
acct = self.apiClient.createAccount(createAcctCmd)
acctId = acct.id
listuser = listUsers.listUsersCmd()
listuser = listUsers.listUsersCmd()
listuser.username = UserName
listuserRes = self.apiClient.listUsers(listuser)
userId = listuserRes[0].id
apiKey = listuserRes[0].apikey
securityKey = listuserRes[0].secretkey
if apiKey is None:
registerUser = registerUserKeys.registerUserKeysCmd()
registerUser.id = userId
registerUserRes = self.apiClient.registerUserKeys(registerUser)
apiKey = registerUserRes.apikey
securityKey = registerUserRes.secretkey
newUserConnection = cloudstackConnection.cloudConnection(self.connection.mgtSvr, self.connection.port,
self.connection.user, self.connection.passwd,
apiKey, securityKey, self.connection.asyncTimeout, self.connection.logging)
self.userApiClient = cloudstackAPIClient.CloudStackAPIClient(newUserConnection)
self.userApiClient.connection = newUserConnection
return self.userApiClient
def close(self):
if self.connection is not None:
self.connection.close()
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):
return self.apiClient
@ -151,18 +157,21 @@ class cloudstackTestClient(object):
'''FixME, httplib has issue if more than one thread submitted'''
def submitCmdsAndWait(self, cmds, workers=1):
if self.asyncJobMgr is None:
self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, self.dbConnection)
return self.asyncJobMgr.submitCmdsAndWait(cmds, workers)
'''submit one job and execute the same job ntimes, with nums_threads of threads'''
def submitJob(self, job, ntimes=1, nums_threads=10, interval=1):
if self.asyncJobMgr is None:
self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, self.dbConnection)
self.asyncJobMgr.submitJobExecuteNtimes(job, ntimes, nums_threads, interval)
'''submit n jobs, execute them with nums_threads of threads'''
'''submit n jobs, execute them with nums_threads of threads'''
def submitJobs(self, jobs, nums_threads=10, interval=1):
if self.asyncJobMgr is None:
self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, self.dbConnection)

View File

@ -37,7 +37,11 @@ class dbConnection(object):
return None
resultRow = []
with contextlib.closing(mysql.connector.connect(host=self.host, port=self.port, user=self.user, password=self.passwd, db=self.database)) as conn:
with contextlib.closing(mysql.connector.connect(host=str(self.host),
port=int(self.port),
user=str(self.user),
password=str(self.passwd),
db=str(self.database))) as conn:
conn.autocommit = True
with contextlib.closing(conn.cursor(buffered=True)) as cursor:
cursor.execute(sql, params)

View File

@ -402,6 +402,7 @@ class deployDataCenters():
self.testClient = \
cloudstackTestClient.cloudstackTestClient(mgt.mgtSvrIp, mgt.port, \
mgt.user, mgt.passwd, \
mgt.apiKey, \
mgt.securityKey, \
logging=self.testClientLogger)
@ -409,6 +410,7 @@ class deployDataCenters():
apiKey, securityKey = self.registerApiKey()
self.testClient = \
cloudstackTestClient.cloudstackTestClient(mgt.mgtSvrIp, 8080, \
mgt.user, mgt.passwd, \
apiKey, securityKey, \
logging=self.testClientLogger)
@ -419,6 +421,11 @@ class deployDataCenters():
dbSvr.passwd, dbSvr.db)
self.apiClient = self.testClient.getApiClient()
"""set hypervisor"""
if mgt.hypervisor:
self.apiClient.hypervisor = mgt.hypervisor
else:
self.apiClient.hypervisor = "XenServer" #Defaults to Xenserver
def updateConfiguration(self, globalCfg):
if globalCfg is None:

View File

@ -5,9 +5,9 @@
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -22,7 +22,7 @@
import marvin
from utils import is_server_ssh_ready, random_gen
from marvin.cloudstackAPI import *
#Import System modules
# Import System modules
import time
import hashlib
import base64
@ -54,8 +54,12 @@ class Domain:
cmd.parentdomainid = parentdomainid
elif "parentdomainid" in services:
cmd.parentdomainid = services["parentdomainid"]
return Domain(apiclient.createDomain(cmd).__dict__)
try:
domain = apiclient.createDomain(cmd)
if domain is not None:
return Domain(domain.__dict__)
except Exception as e:
raise e
def delete(self, apiclient, cleanup=None):
"""Delete an domain"""
@ -83,7 +87,7 @@ class Account:
"""Creates an account"""
cmd = createAccount.createAccountCmd()
#0 - User, 1 - Root Admin, 2 - Domain Admin
# 0 - User, 1 - Root Admin, 2 - Domain Admin
cmd.accounttype = 2 if (admin and domainid) else int(admin)
cmd.email = services["email"]
@ -213,14 +217,15 @@ class VirtualMachine:
else:
self.ssh_port = 22
self.ssh_client = None
#extract out the ipaddress
# extract out the ipaddress
self.ipaddress = self.nic[0].ipaddress
@classmethod
def create(cls, apiclient, services, templateid=None, accountid=None,
domainid=None, zoneid=None, networkids=None, serviceofferingid=None,
securitygroupids=None, projectid=None, startvm=None,
diskofferingid=None, affinitygroupnames=None, hostid=None, mode='basic', method='GET'):
diskofferingid=None, affinitygroupnames=None, group=None,
hostid=None, keypair=None, mode='basic', method='GET'):
"""Create the instance"""
cmd = deployVirtualMachine.deployVirtualMachineCmd()
@ -234,7 +239,13 @@ class VirtualMachine:
cmd.zoneid = zoneid
elif "zoneid" in services:
cmd.zoneid = services["zoneid"]
cmd.hypervisor = services["hypervisor"]
cmd.hypervisor = apiclient.hypervisor
if "displayname" in services:
cmd.displayname = services["displayname"]
if "name" in services:
cmd.name = services["name"]
if accountid:
cmd.account = accountid
@ -256,9 +267,16 @@ class VirtualMachine:
elif "template" in services:
cmd.templateid = services["template"]
if "diskoffering" in services:
if diskofferingid:
cmd.diskofferingid = diskofferingid
elif "diskoffering" in services:
cmd.diskofferingid = services["diskoffering"]
if keypair:
cmd.keypair = keypair
elif "keypair" in services:
cmd.keypair = services["keypair"]
if securitygroupids:
cmd.securitygroupids = [str(sg_id) for sg_id in securitygroupids]
@ -282,6 +300,15 @@ class VirtualMachine:
virtual_machine = apiclient.deployVirtualMachine(cmd, method=method)
if group:
cmd.group = group
virtual_machine = apiclient.deployVirtualMachine(cmd)
if startvm == False:
virtual_machine.ssh_ip = virtual_machine.nic[0].ipaddress
virtual_machine.public_ip = virtual_machine.nic[0].ipaddress
return VirtualMachine(virtual_machine.__dict__, services)
# VM should be in Running state after deploy
timeout = 10
while True:
@ -308,14 +335,14 @@ class VirtualMachine:
virtual_machine.domainid,
services
)
fw_rule = FireWallRule.create(
FireWallRule.create(
apiclient,
ipaddressid=public_ip.ipaddress.id,
protocol='TCP',
cidrlist=['0.0.0.0/0'],
startport=22,
endport=22
)
)
nat_rule = NATRule.create(
apiclient,
virtual_machine,
@ -348,7 +375,13 @@ class VirtualMachine:
cmd.id = self.id
apiclient.rebootVirtualMachine(cmd)
def get_ssh_client(self, ipaddress=None, reconnect=False, port=None):
def recover(self, apiclient):
"""Recover the instance"""
cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
cmd.id = self.id
apiclient.recoverVirtualMachine(cmd)
def get_ssh_client(self, ipaddress=None, reconnect=False, port=None, keyPairFileLocation=None):
"""Get SSH object of VM"""
# If NAT Rules are not created while VM deployment in Advanced mode
@ -358,27 +391,56 @@ class VirtualMachine:
if port:
self.ssh_port = port
if keyPairFileLocation is not None:
self.password = None
if reconnect:
self.ssh_client = is_server_ssh_ready(
self.ssh_ip,
self.ssh_port,
self.username,
self.password
self.password,
keyPairFileLocation=keyPairFileLocation
)
self.ssh_client = self.ssh_client or is_server_ssh_ready(
self.ssh_ip,
self.ssh_port,
self.username,
self.password
self.password,
keyPairFileLocation=keyPairFileLocation
)
return self.ssh_client
def resetSshKey(self, apiclient, **kwargs):
"""Resets SSH key"""
cmd = resetSSHKeyForVirtualMachine.resetSSHKeyForVirtualMachineCmd()
cmd.id = self.id
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.resetSSHKeyForVirtualMachine(cmd))
def update(self, apiclient, **kwargs):
"""Updates the VM data"""
cmd = updateVirtualMachine.updateVirtualMachineCmd()
cmd.id = self.id
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.updateVirtualMachine(cmd))
def delete(self, apiclient):
"""Destroy an Instance"""
cmd = destroyVirtualMachine.destroyVirtualMachineCmd()
cmd.id = self.id
apiclient.destroyVirtualMachine(cmd)
def migrate(self, apiclient, hostid=None):
"""migrate an Instance"""
cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
cmd.virtualmachineid = self.id
if hostid:
cmd.hostid = hostid
apiclient.migrateVirtualMachine(cmd)
def attach_volume(self, apiclient, volume):
"""Attach volume to instance"""
cmd = attachVolume.attachVolumeCmd()
@ -394,7 +456,7 @@ class VirtualMachine:
def add_nic(self, apiclient, networkId):
"""Add a NIC to a VM"""
cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd();
cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd()
cmd.virtualmachineid = self.id
cmd.networkid = networkId
return apiclient.addNicToVirtualMachine(cmd)
@ -413,6 +475,26 @@ class VirtualMachine:
cmd.virtualmachineid = self.id
return apiclient.updateDefaultNicForVirtualMachine(cmd)
def attach_iso(self, apiclient, iso):
"""Attach ISO to instance"""
cmd = attachIso.attachIsoCmd()
cmd.id = iso.id
cmd.virtualmachineid = self.id
return apiclient.attachIso(cmd)
def detach_iso(self, apiclient):
"""Detach ISO to instance"""
cmd = detachIso.detachIsoCmd()
cmd.id = self.id
return apiclient.detachIso(cmd)
def change_service_offering(self, apiclient, serviceOfferingId):
"""Change service offering of the instance"""
cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd()
cmd.id = self.id
cmd.serviceofferingid = serviceOfferingId
return apiclient.changeServiceForVirtualMachine(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""List all VMs matching criteria"""
@ -428,16 +510,14 @@ class VirtualMachine:
cmd.id = self.id
try:
response = apiclient.resetPasswordForVirtualMachine(cmd)
print response
except Exception as e:
raise Exception("Reset Password failed! - %s" % e)
print type(response)
if isinstance(response, list):
return response[0].password
class Volume:
"""Manage Volume Lifecycle
"""Manage Volume Life cycle
"""
def __init__(self, items):
self.__dict__.update(items)
@ -533,7 +613,7 @@ class Volume:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listVolumes(cmd))
def resize(cls, apiclient, **kwargs):
def resize(self, apiclient, **kwargs):
"""Resize a volume"""
cmd = resizeVolume.resizeVolumeCmd()
cmd.id = self.id
@ -541,6 +621,58 @@ class Volume:
return(apiclient.resizeVolume(cmd))
@classmethod
def upload(cls, apiclient, services, zoneid=None, account=None, domainid=None, url=None):
"""Uploads the volume to specified account"""
cmd = uploadVolume.uploadVolumeCmd()
if zoneid:
cmd.zoneid = zoneid
if account:
cmd.account = account
if domainid:
cmd.domainid = domainid
cmd.format = services["format"]
cmd.name = services["diskname"]
if url:
cmd.url = url
else:
cmd.url = services["url"]
return Volume(apiclient.uploadVolume(cmd).__dict__)
def wait_for_upload(self, apiclient, timeout=5, interval=60):
"""Wait for upload"""
# Sleep to ensure template is in proper state before download
time.sleep(interval)
while True:
volume_response = Volume.list(
apiclient,
id=self.id,
zoneid=self.zoneid,
)
if isinstance(volume_response, list):
volume = volume_response[0]
# If volume is ready,
# volume.state = Allocated
if volume.state == 'Uploaded':
break
elif 'Uploading' in volume.state:
time.sleep(interval)
elif 'Installing' not in volume.state:
raise Exception(
"Error in uploading volume: status - %s" %
volume.state)
elif timeout == 0:
break
else:
time.sleep(interval)
timeout = timeout - 1
return
def migrate(cls, apiclient, **kwargs):
"""Migrate a volume"""
cmd = migrateVolume.migrateVolumeCmd()
@ -592,7 +724,7 @@ class Template:
def create(cls, apiclient, services, volumeid=None,
account=None, domainid=None, projectid=None):
"""Create template from Volume"""
#Create template from Virtual machine and Volume ID
# Create template from Virtual machine and Volume ID
cmd = createTemplate.createTemplateCmd()
cmd.displaytext = services["displaytext"]
cmd.name = "-".join([services["name"], random_gen()])
@ -617,7 +749,6 @@ class Template:
cmd.ispublic = services["ispublic"] if "ispublic" in services else False
cmd.isextractable = services["isextractable"] if "isextractable" in services else False
cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False
cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False
if volumeid:
cmd.volumeid = volumeid
@ -637,12 +768,12 @@ class Template:
account=None, domainid=None):
"""Create template from URL"""
#Create template from Virtual machine and Volume ID
# Create template from Virtual machine and Volume ID
cmd = registerTemplate.registerTemplateCmd()
cmd.displaytext = services["displaytext"]
cmd.name = "-".join([services["name"], random_gen()])
cmd.format = services["format"]
cmd.hypervisor = services["hypervisor"]
cmd.hypervisor = apiclient.hypervisor
if "ostypeid" in services:
cmd.ostypeid = services["ostypeid"]
@ -689,7 +820,7 @@ class Template:
def create_from_snapshot(cls, apiclient, snapshot, services,
random_name=True):
"""Create Template from snapshot"""
#Create template from Virtual machine and Snapshot ID
# Create template from Virtual machine and Snapshot ID
cmd = createTemplate.createTemplateCmd()
cmd.displaytext = services["displaytext"]
cmd.name = "-".join([
@ -726,7 +857,7 @@ class Template:
def download(self, apiclient, timeout=5, interval=60):
"""Download Template"""
#Sleep to ensure template is in proper state before download
# Sleep to ensure template is in proper state before download
time.sleep(interval)
while True:
@ -789,7 +920,7 @@ class Iso:
def create(cls, apiclient, services, account=None, domainid=None,
projectid=None):
"""Create an ISO"""
#Create ISO from URL
# Create ISO from URL
cmd = registerIso.registerIsoCmd()
cmd.displaytext = services["displaytext"]
cmd.name = services["name"]
@ -841,7 +972,7 @@ class Iso:
def download(self, apiclient, timeout=5, interval=60):
"""Download an ISO"""
#Ensuring ISO is successfully downloaded
# Ensuring ISO is successfully downloaded
while True:
time.sleep(interval)
@ -853,7 +984,6 @@ class Iso:
response = iso_response[0]
# Again initialize timeout to avoid listISO failure
timeout = 5
print response.status
# Check whether download is in progress(for Ex:10% Downloaded)
# or ISO is 'Successfully Installed'
if response.status == 'Successfully Installed':
@ -940,7 +1070,7 @@ class NATRule:
@classmethod
def create(cls, apiclient, virtual_machine, services, ipaddressid=None,
projectid=None, networkid=None):
projectid=None, openfirewall=False, networkid=None, vpcid=None):
"""Create Port forwarding rule"""
cmd = createPortForwardingRule.createPortForwardingRuleCmd()
@ -951,15 +1081,24 @@ class NATRule:
cmd.privateport = services["privateport"]
cmd.publicport = services["publicport"]
if "privateendport" in services:
cmd.privateendport = services["privateendport"]
if "publicendport" in services:
cmd.publicendport = services["publicendport"]
cmd.protocol = services["protocol"]
cmd.virtualmachineid = virtual_machine.id
if projectid:
cmd.projectid = projectid
if openfirewall:
cmd.openfirewall = True
if networkid:
cmd.networkid = networkid
if vpcid:
cmd.vpcid = vpcid
return NATRule(apiclient.createPortForwardingRule(cmd).__dict__)
def delete(self, apiclient):
@ -985,10 +1124,10 @@ class StaticNATRule:
self.__dict__.update(items)
@classmethod
def create(cls, apiclient, services, ipaddressid=None, vpcid=None):
def create(cls, apiclient, services, ipaddressid=None, networkid=None, vpcid=None):
"""Creates static ip forwarding rule"""
cmd = createIpForwardingRule.createIpForwardingRuleCmd()
cmd = createFirewallRule.createFirewallRuleCmd()
cmd.protocol = services["protocol"]
cmd.startport = services["startport"]
@ -1003,10 +1142,12 @@ class StaticNATRule:
elif "ipaddressid" in services:
cmd.ipaddressid = services["ipaddressid"]
if networkid:
cmd.networkid = networkid
if vpcid:
cmd.vpcid = vpcid
return StaticNATRule(apiclient.createIpForwardingRule(cmd).__dict__)
return StaticNATRule(apiclient.createFirewallRule(cmd).__dict__)
def delete(self, apiclient):
"""Delete IP forwarding rule"""
@ -1024,12 +1165,14 @@ class StaticNATRule:
return(apiclient.listIpForwardingRules(cmd))
@classmethod
def enable(cls, apiclient, ipaddressid, virtualmachineid):
def enable(cls, apiclient, ipaddressid, virtualmachineid, networkid=None):
"""Enables Static NAT rule"""
cmd = enableStaticNat.enableStaticNatCmd()
cmd.ipaddressid = ipaddressid
cmd.virtualmachineid = virtualmachineid
if networkid:
cmd.networkid = networkid
apiclient.enableStaticNat(cmd)
return
@ -1105,6 +1248,14 @@ class ServiceOffering:
if "storagetype" in services:
cmd.storagetype = services["storagetype"]
if "systemvmtype" in services:
cmd.systemvmtype = services['systemvmtype']
if "issystem" in services:
cmd.issystem = services['issystem']
if "tags" in services:
cmd.tags = services["tags"]
# Service Offering private to that domain
if domainid:
cmd.domainid = domainid
@ -1183,20 +1334,25 @@ class NetworkOffering:
cmd.displaytext = "-".join([services["displaytext"], random_gen()])
cmd.name = "-".join([services["name"], random_gen()])
cmd.guestiptype = services["guestiptype"]
cmd.supportedservices = services["supportedservices"]
cmd.supportedservices = ''
if "supportedservices" in services:
cmd.supportedservices = services["supportedservices"]
cmd.traffictype = services["traffictype"]
if "useVpc" in services:
cmd.useVpc = services["useVpc"]
cmd.serviceProviderList = []
for service, provider in services["serviceProviderList"].items():
cmd.serviceProviderList.append({
if "serviceProviderList" in services:
for service, provider in services["serviceProviderList"].items():
cmd.serviceProviderList.append({
'service': service,
'provider': provider
})
if "servicecapabilitylist" in services:
cmd.servicecapabilitylist = []
cmd.serviceCapabilityList = []
for service, capability in services["servicecapabilitylist"].items():
for ctype, value in capability.items():
cmd.servicecapabilitylist.append({
cmd.serviceCapabilityList.append({
'service': service,
'capabilitytype': ctype,
'capabilityvalue': value
@ -1205,6 +1361,7 @@ class NetworkOffering:
cmd.specifyVlan = services["specifyVlan"]
if "specifyIpRanges" in services:
cmd.specifyIpRanges = services["specifyIpRanges"]
cmd.availability = 'Optional'
[setattr(cmd, k, v) for k, v in kwargs.items()]
@ -1275,7 +1432,7 @@ class LoadBalancerRule:
@classmethod
def create(cls, apiclient, services, ipaddressid=None, accountid=None,
networkid=None, projectid=None, domainid=None):
networkid=None, vpcid=None, projectid=None, domainid=None):
"""Create Load balancing Rule"""
cmd = createLoadBalancerRule.createLoadBalancerRuleCmd()
@ -1293,6 +1450,8 @@ class LoadBalancerRule:
if domainid:
cmd.domainid = domainid
if vpcid:
cmd.vpcid = vpcid
cmd.name = services["name"]
cmd.algorithm = services["alg"]
cmd.privateport = services["privateport"]
@ -1359,19 +1518,19 @@ class LoadBalancerRule:
for name, value in param.items():
cmd.param.append({'name': name, 'value': value})
return apiclient.createLBStickinessPolicy(cmd)
def deleteSticky(self, apiclient, id):
"""Deletes stickyness policy"""
cmd = deleteLBStickinessPolicy.deleteLBStickinessPolicyCmd()
cmd.id = id
return apiclient.deleteLBStickinessPolicy(cmd)
@classmethod
def listStickyPolicies(cls, apiclient, lbruleid, **kwargs):
"""Lists stickiness policies for load balancing rule"""
cmd= listLBStickinessPolicies.listLBStickinessPoliciesCmd()
cmd = listLBStickinessPolicies.listLBStickinessPoliciesCmd()
cmd.lbruleid = lbruleid
[setattr(cmd, k, v) for k, v in kwargs.items()]
return apiclient.listLBStickinessPolicies(cmd)
@ -1396,7 +1555,7 @@ class Cluster:
"""Create Cluster"""
cmd = addCluster.addClusterCmd()
cmd.clustertype = services["clustertype"]
cmd.hypervisor = services["hypervisor"]
cmd.hypervisor = apiclient.hypervisor
if zoneid:
cmd.zoneid = zoneid
@ -1446,7 +1605,7 @@ class Host:
"""Create Host in cluster"""
cmd = addHost.addHostCmd()
cmd.hypervisor = services["hypervisor"]
cmd.hypervisor = apiclient.hypervisor
cmd.url = services["url"]
cmd.clusterid = cluster.id
@ -1493,6 +1652,29 @@ class Host:
cmd.id = self.id
return apiclient.prepareHostForMaintenance(cmd)
@classmethod
def enableMaintenance(cls, apiclient, id):
"""enables maintainance mode Host"""
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
cmd.id = id
return apiclient.prepareHostForMaintenance(cmd)
def cancelMaintenance(self, apiclient):
"""Cancels maintainance mode Host"""
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
cmd.id = self.id
return apiclient.cancelHostMaintenance(cmd)
@classmethod
def cancelMaintenance(cls, apiclient, id):
"""Cancels maintainance mode Host"""
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
cmd.id = id
return apiclient.cancelHostMaintenance(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""List all Hosts matching criteria"""
@ -1586,7 +1768,8 @@ class Network:
@classmethod
def create(cls, apiclient, services, accountid=None, domainid=None,
networkofferingid=None, projectid=None, zoneid=None,
networkofferingid=None, projectid=None,
subdomainaccess=None, zoneid=None,
gateway=None, netmask=None, vpcid=None, guestcidr=None):
"""Create Network for account"""
cmd = createNetwork.createNetworkCmd()
@ -1603,6 +1786,9 @@ class Network:
elif "zoneid" in services:
cmd.zoneid = services["zoneid"]
if subdomainaccess is not None:
cmd.subdomainaccess = subdomainaccess
if gateway:
cmd.gateway = gateway
elif "gateway" in services:
@ -1717,7 +1903,7 @@ class Vpn:
@classmethod
def create(cls, apiclient, publicipid, account=None, domainid=None,
projectid=None, vpcid=None):
projectid=None, networkid=None, vpcid=None):
"""Create VPN for Public IP address"""
cmd = createRemoteAccessVpn.createRemoteAccessVpnCmd()
cmd.publicipid = publicipid
@ -1727,6 +1913,8 @@ class Vpn:
cmd.domainid = domainid
if projectid:
cmd.projectid = projectid
if networkid:
cmd.networkid = networkid
if vpcid:
cmd.vpcid = vpcid
return Vpn(apiclient.createRemoteAccessVpn(cmd).__dict__)
@ -1755,10 +1943,11 @@ class VpnUser:
@classmethod
def create(cls, apiclient, username, password, account=None, domainid=None,
projectid=None):
projectid=None, rand_name=True):
"""Create VPN user"""
cmd = addVpnUser.addVpnUserCmd()
cmd.username = username
cmd.username = "-".join([username,
random_gen()]) if rand_name else username
cmd.password = password
if account:
@ -1997,6 +2186,7 @@ class PhysicalNetwork:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return map(lambda pn : PhysicalNetwork(pn.__dict__), apiclient.listPhysicalNetworks(cmd))
class SecurityGroup:
"""Manage Security Groups"""
@ -2364,6 +2554,104 @@ class NetworkServiceProvider:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listNetworkServiceProviders(cmd))
class Router:
"""Manage router life cycle"""
def __init__(self, items):
self.__dict__.update(items)
@classmethod
def start(cls, apiclient, id):
"""Starts the router"""
cmd = startRouter.startRouterCmd()
cmd.id = id
return apiclient.startRouter(cmd)
@classmethod
def stop(cls, apiclient, id, forced=None):
"""Stops the router"""
cmd = stopRouter.stopRouterCmd()
cmd.id = id
if forced:
cmd.forced = forced
return apiclient.stopRouter(cmd)
@classmethod
def reboot(cls, apiclient, id):
"""Reboots the router"""
cmd = rebootRouter.rebootRouterCmd()
cmd.id = id
return apiclient.rebootRouter(cmd)
@classmethod
def destroy(cls, apiclient, id):
"""Destroy the router"""
cmd = destroyRouter.destroyRouterCmd()
cmd.id = id
return apiclient.destroyRouter(cmd)
@classmethod
def change_service_offering(cls, apiclient, id, serviceofferingid):
"""Change service offering of the router"""
cmd = changeServiceForRouter.changeServiceForRouterCmd()
cmd.id = id
cmd.serviceofferingid = serviceofferingid
return apiclient.changeServiceForRouter(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""List routers"""
cmd = listRouters.listRoutersCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listRouters(cmd))
class Tag:
"""Manage tags"""
def __init__(self, items):
self.__dict__.update(items)
@classmethod
def create(cls, apiclient, resourceIds, resourceType, tags):
"""Create tags"""
cmd = createTags.createTagsCmd()
cmd.resourceIds = resourceIds
cmd.resourcetype = resourceType
cmd.tags = []
for key, value in tags.items():
cmd.tags.append({
'key': key,
'value': value
})
return Tag(apiclient.createTags(cmd).__dict__)
def delete(self, apiclient, resourceIds, resourceType, tags):
"""Delete tags"""
cmd = deleteTags.deleteTagsCmd()
cmd.resourceIds = resourceIds
cmd.resourcetype = resourceType
cmd.tags = []
for key, value in tags.items():
cmd.tags.append({
'key': key,
'value': value
})
apiclient.deleteTags(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""List all tags matching the criteria"""
cmd = listTags.listTagsCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listTags(cmd))
class VpcOffering:
"""Manage VPC offerings"""
@ -2417,7 +2705,7 @@ class VPC:
@classmethod
def create(cls, apiclient, services, vpcofferingid,
zoneid, networkDomain=None, account=None, domainid=None):
zoneid, networkDomain=None, account=None, domainid=None):
"""Creates the virtual private connection (VPC)"""
cmd = createVPC.createVPCCmd()
@ -2467,6 +2755,40 @@ class VPC:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listVPCs(cmd))
class PrivateGateway:
"""Manage private gateway lifecycle"""
def create(cls, apiclient, gateway, ipaddress, netmask, vlan, vpcid,
physicalnetworkid=None):
"""Create private gateway"""
cmd = createPrivateGateway.createPrivateGatewayCmd()
cmd.gateway = gateway
cmd.ipaddress = ipaddress
cmd.netmask = netmask
cmd.vlan = vlan
cmd.vpcid = vpcid
if physicalnetworkid:
cmd.physicalnetworkid = physicalnetworkid
return PrivateGateway(apiclient.createPrivateGateway(cmd).__dict__)
def delete(self, apiclient):
"""Delete private gateway"""
cmd = deletePrivateGateway.deletePrivateGatewayCmd()
cmd.id = self.id
return apiclient.deletePrivateGateway(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""List private gateways"""
cmd = listPrivateGateways.listPrivateGatewaysCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listPrivateGateways(cmd))
class AffinityGroup:
def __init__(self, items):
self.__dict__.update(items)
@ -2495,9 +2817,35 @@ class AffinityGroup:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listVPCs(cmd))
class StaticRoute:
"""Manage static route lifecycle"""
@classmethod
def create(cls, apiclient, cidr, gatewayid):
"""Create static route"""
cmd = createStaticRoute.createStaticRouteCmd()
cmd.cidr = cidr
cmd.gatewayid = gatewayid
return StaticRoute(apiclient.createStaticRoute(cmd).__dict__)
def delete(self, apiclient):
"""Delete static route"""
cmd = deleteStaticRoute.deleteStaticRouteCmd()
cmd.id = self.id
return apiclient.deleteStaticRoute(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""List static route"""
cmd = listStaticRoutes.listStaticRoutesCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listStaticRoutes(cmd))
class VNMC:
"""Manage VNMC lifecycle"""
def __init__(self, items):
self.__dict__.update(items)
@ -2526,13 +2874,153 @@ class VNMC:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listCiscoVnmcResources(cmd))
class ASA1000V:
"""Manage ASA 1000v lifecycle"""
class SSHKeyPair:
"""Manage SSH Key pairs"""
def __init__(self, items, services):
self.__dict__.update(items)
@classmethod
def create(cls, apiclient, name=None, account=None,
domainid=None, projectid=None):
"""Creates SSH keypair"""
cmd = createSSHKeyPair.createSSHKeyPairCmd()
cmd.name = name
if account is not None:
cmd.account = account
if domainid is not None:
cmd.domainid = domainid
if projectid is not None:
cmd.projectid = projectid
return (apiclient.createSSHKeyPair(cmd))
def delete(self, apiclient):
"""Delete SSH key pair"""
cmd = deleteSSHKeyPair.deleteSSHKeyPairCmd()
cmd.name = self.name
apiclient.deleteSSHKeyPair(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""List all SSH key pairs"""
cmd = listSSHKeyPairs.listSSHKeyPairsCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listSSHKeyPairs(cmd))
class Capacities:
"""Manage Capacities"""
@classmethod
def list(cls, apiclient, **kwargs):
"""Lists capacities"""
cmd = listCapacity.listCapacityCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listCapacity(cmd))
class Alert:
"""Manage alerts"""
@classmethod
def list(cls, apiclient, **kwargs):
"""Lists alerts"""
cmd = listAlerts.listAlertsCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listAlerts(cmd))
class InstanceGroup:
"""Manage VM instance groups"""
def __init__(self, items):
self.__dict__.update(items)
@classmethod
def create(cls, apiclient, name=None, account=None, domainid=None,
projectid=None, networkid=None, rand_name=True):
"""Creates instance groups"""
cmd = createInstanceGroup.createInstanceGroupCmd()
cmd.name = "-".join([name, random_gen()]) if rand_name else name
if account is not None:
cmd.account = account
if domainid is not None:
cmd.domainid = domainid
if projectid is not None:
cmd.projectid = projectid
if networkid is not None:
cmd.networkid = networkid
return InstanceGroup(apiclient.createInstanceGroup(cmd).__dict__)
def delete(self, apiclient):
"""Delete instance group"""
cmd = deleteInstanceGroup.deleteInstanceGroupCmd()
cmd.id = self.id
apiclient.deleteInstanceGroup(cmd)
def update(self, apiclient, **kwargs):
"""Updates the instance groups"""
cmd = updateInstanceGroup.updateInstanceGroupCmd()
cmd.id = self.id
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.updateInstanceGroup(cmd))
@classmethod
def list(cls, apiclient, **kwargs):
"""List all instance groups"""
cmd = listInstanceGroups.listInstanceGroupsCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.listInstanceGroups(cmd))
def startInstances(self, apiclient):
"""Starts all instances in a VM tier"""
cmd = startVirtualMachine.startVirtualMachineCmd()
cmd.group = self.id
return apiclient.startVirtualMachine(cmd)
def stopInstances(self, apiclient):
"""Stops all instances in a VM tier"""
cmd = stopVirtualMachine.stopVirtualMachineCmd()
cmd.group = self.id
return apiclient.stopVirtualMachine(cmd)
def rebootInstances(self, apiclient):
"""Reboot all instances in a VM tier"""
cmd = rebootVirtualMachine.rebootVirtualMachineCmd()
cmd.group = self.id
return apiclient.rebootVirtualMachine(cmd)
def deleteInstances(self, apiclient):
"""Stops all instances in a VM tier"""
cmd = destroyVirtualMachine.destroyVirtualMachineCmd()
cmd.group = self.id
return apiclient.destroyVirtualMachine(cmd)
def changeServiceOffering(self, apiclient, serviceOfferingId):
"""Change service offering of the vm tier"""
cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd()
cmd.group = self.id
cmd.serviceofferingid = serviceOfferingId
return apiclient.changeServiceForVirtualMachine(cmd)
def recoverInstances(self, apiclient):
"""Recover the instances from vm tier"""
cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
cmd.group = self.id
apiclient.recoverVirtualMachine(cmd)
class ASA1000V:
"""Manage ASA 1000v lifecycle"""
def create(cls, apiclient, hostname, insideportprofile, clusterid, physicalnetworkid):
"""Registers ASA 1000v appliance"""

View File

@ -106,12 +106,17 @@ def cleanup_resources(api_client, resources):
obj.delete(api_client)
def is_server_ssh_ready(ipaddress, port, username, password, retries=50):
def is_server_ssh_ready(ipaddress, port, username, password, retries=50, keyPairFileLocation=None):
"""Return ssh handle else wait till sshd is running"""
loop_cnt = retries
while True:
try:
ssh = remoteSSHClient(ipaddress, port, username, password)
ssh = remoteSSHClient(
host=ipaddress,
port=port,
user=username,
passwd=password,
keyPairFileLocation=keyPairFileLocation)
except Exception as e:
if loop_cnt == 0:
raise e
@ -149,12 +154,16 @@ def fetch_api_client(config_file='datacenterCfg'):
)
def get_process_status(hostip, port, username, password, linklocalip, process):
def get_process_status(hostip, port, username, password, linklocalip, process, hypervisor=None):
"""Double hop and returns a process status"""
#SSH to the machine
ssh = remoteSSHClient(hostip, port, username, password)
ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no "
if str(hypervisor).lower() == 'vmware':
ssh_command = "ssh -i /var/lib/cloud/management/.ssh/id_rsa -ostricthostkeychecking=no "
else:
ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no "
ssh_command = ssh_command + \
"-oUserKnownHostsFile=/dev/null -p 3922 %s %s" % (
linklocalip,

View File

@ -23,11 +23,12 @@ import logging
from contextlib import closing
class remoteSSHClient(object):
def __init__(self, host, port, user, passwd, retries = 10, log_lvl=logging.INFO):
def __init__(self, host, port, user, passwd, retries = 10, log_lvl=logging.INFO, keyPairFileLocation=None):
self.host = host
self.port = port
self.user = user
self.passwd = passwd
self.keyPairFile = keyPairFileLocation
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.logger = logging.getLogger('sshClient')
@ -38,8 +39,19 @@ class remoteSSHClient(object):
retry_count = retries
while True:
try:
self.ssh.connect(str(host),int(port), user, passwd)
self.logger.debug("SSH connect: %s@%s with passwd %s"%(user, str(host), passwd))
if keyPairFileLocation == None:
self.ssh.connect(str(host),int(port), user, passwd)
self.logger.debug("SSH connect: %s@%s with passwd %s"%(user, str(host), passwd))
else:
self.ssh.connect(
hostname=str(host),
port=int(port),
username=str(user),
key_filename=str(keyPairFileLocation),
look_for_keys=False
)
self.logger.debug("connecting to server %s with user %s key %s"%(str(host), user, keyPairFileLocation))
self.logger.debug("SSH connect: %s@%s with passwd %s"%(user, str(host), passwd))
except paramiko.SSHException, sshex:
if retry_count == 0:
raise cloudstackException.InvalidParameterException(repr(sshex))