mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
141 lines
6.6 KiB
Python
141 lines
6.6 KiB
Python
import httplib
|
|
import urllib
|
|
import base64
|
|
import hmac
|
|
import hashlib
|
|
import json
|
|
import xml.dom.minidom
|
|
import types
|
|
import time
|
|
import inspect
|
|
import cloudstackException
|
|
from cloudstackAPI import *
|
|
import jsonHelper
|
|
|
|
class cloudConnection(object):
|
|
def __init__(self, mgtSvr, port=8096, apiKey = None, securityKey = None, asyncTimeout=3600, logging=None):
|
|
self.apiKey = apiKey
|
|
self.securityKey = securityKey
|
|
self.mgtSvr = mgtSvr
|
|
self.connection = httplib.HTTPConnection("%s:%d"%(mgtSvr,port))
|
|
self.port = port
|
|
self.logging = logging
|
|
if port == 8096:
|
|
self.auth = False
|
|
else:
|
|
self.auth = True
|
|
|
|
self.asyncTimeout = asyncTimeout
|
|
|
|
def close(self):
|
|
try:
|
|
self.connection.close()
|
|
except:
|
|
pass
|
|
|
|
def __copy__(self):
|
|
return cloudConnection(self.mgtSvr, self.port, self.apiKey, self.securityKey, self.asyncTimeout, self.logging)
|
|
|
|
def make_request_with_auth(self, command, requests={}):
|
|
requests["command"] = command
|
|
requests["apiKey"] = self.apiKey
|
|
requests["response"] = "json"
|
|
requests = zip(requests.keys(), requests.values())
|
|
requests.sort(key=lambda x: str.lower(x[0]))
|
|
|
|
requestUrl = "&".join(["=".join([request[0], urllib.quote_plus(str(request[1]))]) for request in requests])
|
|
hashStr = "&".join(["=".join([str.lower(request[0]), str.lower(urllib.quote_plus(str(request[1]))).replace("+", "%20")]) for request in requests])
|
|
|
|
sig = urllib.quote_plus(base64.encodestring(hmac.new(self.securityKey, hashStr, hashlib.sha1).digest()).strip())
|
|
|
|
requestUrl += "&signature=%s"%sig
|
|
|
|
self.connection.request("GET", "/client/api?%s"%requestUrl)
|
|
return self.connection.getresponse().read()
|
|
|
|
def make_request_without_auth(self, command, requests={}):
|
|
requests["command"] = command
|
|
requests["response"] = "json"
|
|
requests = zip(requests.keys(), requests.values())
|
|
requestUrl = "&".join(["=".join([request[0], urllib.quote_plus(str(request[1]))]) for request in requests])
|
|
self.connection.request("GET", "/&%s"%requestUrl)
|
|
return self.connection.getresponse().read()
|
|
|
|
def pollAsyncJob(self, jobId, response):
|
|
cmd = queryAsyncJobResult.queryAsyncJobResultCmd()
|
|
cmd.jobid = jobId
|
|
|
|
while self.asyncTimeout > 0:
|
|
asyncResonse = self.make_request(cmd, response, True)
|
|
|
|
if asyncResonse.jobstatus == 2:
|
|
raise cloudstackException.cloudstackAPIException("asyncquery", asyncResonse.jobresult)
|
|
elif asyncResonse.jobstatus == 1:
|
|
return asyncResonse
|
|
|
|
time.sleep(5)
|
|
self.asyncTimeout = self.asyncTimeout - 5
|
|
|
|
raise cloudstackException.cloudstackAPIException("asyncquery", "Async job timeout")
|
|
|
|
def make_request(self, cmd, response = None, raw=False):
|
|
commandName = cmd.__class__.__name__.replace("Cmd", "")
|
|
isAsync = "false"
|
|
requests = {}
|
|
required = []
|
|
for attribute in dir(cmd):
|
|
if attribute != "__doc__" and attribute != "__init__" and attribute != "__module__":
|
|
if attribute == "isAsync":
|
|
isAsync = getattr(cmd, attribute)
|
|
elif attribute == "required":
|
|
required = getattr(cmd, attribute)
|
|
else:
|
|
requests[attribute] = getattr(cmd, attribute)
|
|
|
|
for requiredPara in required:
|
|
if requests[requiredPara] is None:
|
|
raise cloudstackException.cloudstackAPIException(commandName, "%s is required"%requiredPara)
|
|
'''remove none value'''
|
|
for param, value in requests.items():
|
|
if value is None:
|
|
requests.pop(param)
|
|
elif isinstance(value, list):
|
|
if len(value) == 0:
|
|
requests.pop(param)
|
|
else:
|
|
if not isinstance(value[0], dict):
|
|
requests[param] = ",".join(value)
|
|
else:
|
|
requests.pop(param)
|
|
i = 0
|
|
for v in value:
|
|
for key, val in v.iteritems():
|
|
requests["%s[%d].%s"%(param,i,key)] = val
|
|
i = i + 1
|
|
|
|
if self.logging is not None:
|
|
self.logging.debug("sending command: %s %s"%(commandName, str(requests)))
|
|
result = None
|
|
if self.auth:
|
|
result = self.make_request_with_auth(commandName, requests)
|
|
else:
|
|
result = self.make_request_without_auth(commandName, requests)
|
|
|
|
if self.logging is not None:
|
|
self.logging.debug("got result: " + result)
|
|
if result is None:
|
|
return None
|
|
|
|
result = jsonHelper.getResultObj(result, response)
|
|
if raw or isAsync == "false":
|
|
return result
|
|
else:
|
|
asynJobId = result.jobid
|
|
result = self.pollAsyncJob(asynJobId, response)
|
|
return result.jobresult
|
|
|
|
if __name__ == '__main__':
|
|
xml = '<?xml version="1.0" encoding="ISO-8859-1"?><deployVirtualMachineResponse><virtualmachine><id>407</id><name>i-1-407-RS3</name><displayname>i-1-407-RS3</displayname><account>system</account><domainid>1</domainid><domain>ROOT</domain><created>2011-07-30T14:45:19-0700</created><state>Running</state><haenable>false</haenable><zoneid>1</zoneid><zonename>CA1</zonename><hostid>3</hostid><hostname>kvm-50-205</hostname><templateid>4</templateid><templatename>CentOS 5.5(64-bit) no GUI (KVM)</templatename><templatedisplaytext>CentOS 5.5(64-bit) no GUI (KVM)</templatedisplaytext><passwordenabled>false</passwordenabled><serviceofferingid>1</serviceofferingid><serviceofferingname>Small Instance</serviceofferingname><cpunumber>1</cpunumber><cpuspeed>500</cpuspeed><memory>512</memory><guestosid>112</guestosid><rootdeviceid>0</rootdeviceid><rootdevicetype>NetworkFilesystem</rootdevicetype><nic><id>380</id><networkid>203</networkid><netmask>255.255.255.0</netmask><gateway>65.19.181.1</gateway><ipaddress>65.19.181.110</ipaddress><isolationuri>vlan://65</isolationuri><broadcasturi>vlan://65</broadcasturi><traffictype>Guest</traffictype><type>Direct</type><isdefault>true</isdefault><macaddress>06:52:da:00:00:08</macaddress></nic><hypervisor>KVM</hypervisor></virtualmachine></deployVirtualMachineResponse>'
|
|
conn = cloudConnection(None)
|
|
|
|
print conn.paraseReturnXML(xml, deployVirtualMachine.deployVirtualMachineResponse()) |