diff --git a/tools/marvin/marvin/jsonHelper.py b/tools/marvin/marvin/jsonHelper.py index 79a6369499c..a583d1d9116 100644 --- a/tools/marvin/marvin/jsonHelper.py +++ b/tools/marvin/marvin/jsonHelper.py @@ -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 @@ -20,6 +20,7 @@ import json import inspect from cloudstackAPI import * + class jsonLoader: '''The recursive class for building and representing objects with.''' def __init__(self, obj): @@ -33,18 +34,23 @@ class jsonLoader: else: setattr(self, k, v) else: - setattr(self,k,v) + setattr(self, k, v) + def __getattr__(self, val): if val in self.__dict__: return self.__dict__[val] else: return None + def __repr__(self): - return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems())) + return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) + in self.__dict__.iteritems())) + def __str__(self): - return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems())) - - + return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) + in self.__dict__.iteritems())) + + class jsonDump: @staticmethod def __serialize(obj): @@ -59,7 +65,7 @@ class jsonDump: if (isinstance(obj[key], list) and len(obj[key]) == 0): continue newobj[key] = jsonDump.__serialize(obj[key]) - + return newobj elif isinstance(obj, list): return [jsonDump.__serialize(item) for item in obj] @@ -68,41 +74,51 @@ class jsonDump: elif hasattr(obj, '__dict__'): return jsonDump.__serialize(obj.__dict__) else: - return repr(obj) # Don't know how to handle, convert to string - + return repr(obj) # Don't know how to handle, convert to string + @staticmethod def dump(obj): return jsonDump.__serialize(obj) + def getclassFromName(cmd, name): module = inspect.getmodule(cmd) return getattr(module, name)() + def finalizeResultObj(result, responseName, responsecls): - if responsecls is None and responseName.endswith("response") and responseName != "queryasyncjobresultresponse": + responsclsLoadable = (responsecls is None + and responseName.endswith("response") + and responseName != "queryasyncjobresultresponse") + if responsclsLoadable: '''infer the response class from the name''' moduleName = responseName.replace("response", "") try: responsecls = getclassFromName(moduleName, responseName) except: pass - - if responseName is not None and responseName == "queryasyncjobresultresponse" and responsecls is not None and result.jobresult is not None: - result.jobresult = finalizeResultObj(result.jobresult, None, responsecls) + + responsNameValid = (responseName is not None + and responseName == "queryasyncjobresultresponse" + and responsecls is not None + and result.jobresult is not None) + if responsNameValid: + result.jobresult = finalizeResultObj(result.jobresult, None, + responsecls) return result elif responsecls is not None: - for k,v in result.__dict__.iteritems(): + for k, v in result.__dict__.iteritems(): if k in responsecls.__dict__: return result - + attr = result.__dict__.keys()[0] - + value = getattr(result, attr) if not isinstance(value, jsonLoader): return result - + findObj = False - for k,v in value.__dict__.iteritems(): + for k, v in value.__dict__.iteritems(): if k in responsecls.__dict__: findObj = True break @@ -113,20 +129,24 @@ def finalizeResultObj(result, responseName, responsecls): else: return result + def getResultObj(returnObj, responsecls=None): if len(returnObj) == 0: return None - responseName = filter(lambda a: a!=u'cloudstack-version', returnObj.keys())[0] - + responseName = filter(lambda a: a != u'cloudstack-version', + returnObj.keys())[0] + response = returnObj[responseName] if len(response) == 0: return None - + result = jsonLoader(response) if result.errorcode is not None: - errMsg = "errorCode: %s, errorText:%s"%(result.errorcode, result.errortext) - raise cloudstackException.cloudstackAPIException(responseName.replace("response", ""), errMsg) - + errMsg = "errorCode: %s, errorText:%s" % (result.errorcode, + result.errortext) + respname = responseName.replace("response", "") + raise cloudstackException.cloudstackAPIException(respname, errMsg) + if result.count is not None: for key in result.__dict__.iterkeys(): if key == "count": @@ -135,57 +155,225 @@ def getResultObj(returnObj, responsecls=None): return getattr(result, key) else: return finalizeResultObj(result, responseName, responsecls) - + if __name__ == "__main__": - result = '{ "listnetworkserviceprovidersresponse" : { "count":1 ,"networkserviceprovider" : [ {"name":"VirtualRouter","physicalnetworkid":"ad2948fc-1054-46c7-b1c7-61d990b86710","destinationphysicalnetworkid":"0","state":"Disabled","id":"d827cae4-4998-4037-95a2-55b92b6318b1","servicelist":["Vpn","Dhcp","Dns","Gateway","Firewall","Lb","SourceNat","StaticNat","PortForwarding","UserData"]} ] } }' + result = '''{ "listnetworkserviceprovidersresponse" : { "count" : 1, + "networkserviceprovider" : [ { "destinationphysicalnetworkid" : "0", + "id" : "d827cae4-4998-4037-95a2-55b92b6318b1", + "name" : "VirtualRouter", + "physicalnetworkid" : "ad2948fc-1054-46c7-b1c7-61d990b86710", + "servicelist" : [ "Vpn", + "Dhcp", + "Dns", + "Gateway", + "Firewall", + "Lb", + "SourceNat", + "StaticNat", + "PortForwarding", + "UserData" + ], + "state" : "Disabled" + } ] + } }''' nsp = getResultObj(result) print nsp[0].id - - result = '{ "listzonesresponse" : { "count":1 ,"zone" : [ {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"8.8.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"5e818a11-6b00-3429-9a07-e27511d3169a","dhcpprovider":"DhcpServer"} ] } }' + + result = '''{ "listzonesresponse" : { + "count" : 1, + "zone" : [ { "allocationstate" : "Enabled", + "dhcpprovider" : "DhcpServer", + "dns1" : "8.8.8.8", + "dns2" : "8.8.4.4", + "id" : 1, + "internaldns1" : "192.168.110.254", + "internaldns2" : "192.168.110.253", + "name" : "test0", + "networktype" : "Basic", + "securitygroupsenabled" : true, + "zonetoken" : "5e818a11-6b00-3429-9a07-e27511d3169a" + } ] + } +}''' zones = getResultObj(result) print zones[0].id res = authorizeSecurityGroupIngress.authorizeSecurityGroupIngressResponse() - result = '{ "queryasyncjobresultresponse" : {"jobid":10,"jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"securitygroup":{"id":1,"name":"default","description":"Default Security Group","account":"admin","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":1,"protocol":"tcp","startport":22,"endport":22,"securitygroupname":"default","account":"a"},{"ruleid":2,"protocol":"tcp","startport":22,"endport":22,"securitygroupname":"default","account":"b"}]}}} }' + result = '''{ + "queryasyncjobresultresponse" : { + "jobid" : 10, + "jobprocstatus" : 0, + "jobresult" : { + "securitygroup" : { + "account" : "admin", + "description" : "Default Security Group", + "domain" : "ROOT", + "domainid" : 1, + "id" : 1, + "ingressrule" : [ { "account" : "a", + "endport" : 22, + "protocol" : "tcp", + "ruleid" : 1, + "securitygroupname" : "default", + "startport" : 22 + }, + { "account" : "b", + "endport" : 22, + "protocol" : "tcp", + "ruleid" : 2, + "securitygroupname" : "default", + "startport" : 22 + } + ], + "name" : "default" + } + }, + "jobresultcode" : 0, + "jobresulttype" : "object", + "jobstatus" : 1 + } +}''' asynJob = getResultObj(result, res) print asynJob.jobid, repr(asynJob.jobresult) print asynJob.jobresult.ingressrule[0].account - - result = '{ "queryasyncjobresultresponse" : {"errorcode" : 431, "errortext" : "Unable to execute API command queryasyncjobresultresponse due to missing parameter jobid"} }' + + result = '''{ + "queryasyncjobresultresponse" : { + "errorcode" : 431, + "errortext" : +"Unable to execute API command queryasyncjobresultresponse due to missing parameter jobid" + } +}''' try: asynJob = getResultObj(result) except cloudstackException.cloudstackAPIException, e: print e - + result = '{ "queryasyncjobresultresponse" : {} }' asynJob = getResultObj(result) print asynJob - + result = '{}' asynJob = getResultObj(result) print asynJob - - result = '{ "createzoneresponse" : { "zone" : {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"8.8.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"3442f287-e932-3111-960b-514d1f9c4610","dhcpprovider":"DhcpServer"} } }' + + result = '''{ + "createzoneresponse" : { + "zone" : { + "id":1,"name":"test0","dns1":"8.8.8.8","dns2":"8.8.4.4", + "internaldns1":"192.168.110.254","internaldns2":"192.168.110.253", + "networktype":"Basic","securitygroupsenabled":true, + "allocationstate":"Enabled", + "zonetoken":"3442f287-e932-3111-960b-514d1f9c4610", + "dhcpprovider":"DhcpServer" + } + } +}''' res = createZone.createZoneResponse() zone = getResultObj(result, res) print zone.id - + result = '{ "attachvolumeresponse" : {"jobid":24} }' res = attachVolume.attachVolumeResponse() res = getResultObj(result, res) print res - + result = '{ "listtemplatesresponse" : { } }' print getResultObj(result, listTemplates.listTemplatesResponse()) - - result = '{ "queryasyncjobresultresponse" : {"jobid":34,"jobstatus":2,"jobprocstatus":0,"jobresultcode":530,"jobresulttype":"object","jobresult":{"errorcode":431,"errortext":"Please provide either a volume id, or a tuple(device id, instance id)"}} }' + + result = '''{ + "queryasyncjobresultresponse" : { + "jobid":34,"jobstatus":2,"jobprocstatus":0,"jobresultcode":530, + "jobresulttype":"object","jobresult":{ + "errorcode":431, + "errortext": +"Please provide either a volume id, or a tuple(device id, instance id)" + } + } +}''' print getResultObj(result, listTemplates.listTemplatesResponse()) - result = '{ "queryasyncjobresultresponse" : {"jobid":41,"jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"virtualmachine":{"id":37,"name":"i-2-37-TEST","displayname":"i-2-37-TEST","account":"admin","domainid":1,"domain":"ROOT","created":"2011-08-25T11:13:42-0700","state":"Running","haenable":false,"zoneid":1,"zonename":"test0","hostid":5,"hostname":"SimulatedAgent.1e629060-f547-40dd-b792-57cdc4b7d611","templateid":10,"templatename":"CentOS 5.3(64-bit) no GUI (Simulator)","templatedisplaytext":"CentOS 5.3(64-bit) no GUI (Simulator)","passwordenabled":false,"serviceofferingid":7,"serviceofferingname":"Small Instance","cpunumber":1,"cpuspeed":500,"memory":512,"guestosid":11,"rootdeviceid":0,"rootdevicetype":"NetworkFilesystem","securitygroup":[{"id":1,"name":"default","description":"Default Security Group"}],"nic":[{"id":43,"networkid":204,"netmask":"255.255.255.0","gateway":"192.168.1.1","ipaddress":"192.168.1.27","isolationuri":"ec2://untagged","broadcasturi":"vlan://untagged","traffictype":"Guest","type":"Direct","isdefault":true,"macaddress":"06:56:b8:00:00:53"}],"hypervisor":"Simulator"}}} }' - - result='{ "queryasyncjobresultresponse" : {"accountid":"30910093-22e4-4d3c-a464-8b36b60c8001","userid":"cb0aeca3-42ee-47c4-838a-2cd9053441f2","cmd":"com.cloud.api.commands.DeployVMCmd","jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"virtualmachine":{"id":"d2e4d724-e089-4e59-be8e-647674059016","name":"i-2-14-TEST","displayname":"i-2-14-TEST","account":"admin","domainid":"8cfafe79-81eb-445e-8608-c5b7c31fc3a5","domain":"ROOT","created":"2012-01-15T18:30:11+0530","state":"Running","haenable":false,"zoneid":"30a397e2-1c85-40c0-8463-70278952b046","zonename":"Sandbox-simulator","hostid":"cc0105aa-a2a9-427a-8ad7-4d835483b8a9","hostname":"SimulatedAgent.9fee20cc-95ca-48b1-8268-5513d6e83a1b","templateid":"d92570fa-bf40-44db-9dff-45cc7042604d","templatename":"CentOS 5.3(64-bit) no GUI (Simulator)","templatedisplaytext":"CentOS 5.3(64-bit) no GUI (Simulator)","passwordenabled":false,"serviceofferingid":"3734d632-797b-4f1d-ac62-33f9cf70d005","serviceofferingname":"Sample SO","cpunumber":1,"cpuspeed":100,"memory":128,"guestosid":"1e36f523-23e5-4e90-869b-a1b5e9ba674d","rootdeviceid":0,"rootdevicetype":"NetworkFilesystem","nic":[{"id":"4d3ab903-f511-4dab-8a6d-c2a3b51de7e0","networkid":"faeb7f24-a4b9-447d-bec6-c4956c4ab0f6","netmask":"255.255.240.0","gateway":"10.6.240.1","ipaddress":"10.6.253.89","isolationuri":"vlan://211","broadcasturi":"vlan://211","traffictype":"Guest","type":"Isolated","isdefault":true,"macaddress":"02:00:04:74:00:09"}],"hypervisor":"Simulator"}},"created":"2012-01-15T18:30:11+0530","jobid":"f4a13f28-fcd6-4d7f-b9cd-ba7eb5a5701f"} }' - vm = getResultObj(result, deployVirtualMachine.deployVirtualMachineResponse()) + result = '''{ + "queryasyncjobresultresponse" : { + "jobid":41,"jobstatus":1,"jobprocstatus":0, + "jobresultcode":0,"jobresulttype":"object","jobresult":{ + "virtualmachine":{ + "id":37,"name":"i-2-37-TEST", + "displayname":"i-2-37-TEST","account":"admin", + "domainid":1,"domain":"ROOT", + "created":"2011-08-25T11:13:42-0700", + "state":"Running","haenable":false,"zoneid":1, + "zonename":"test0","hostid":5, + "hostname": + "SimulatedAgent.1e629060-f547-40dd-b792-57cdc4b7d611", + "templateid":10, + "templatename":"CentOS 5.3(64-bit) no GUI (Simulator)", + "templatedisplaytext": + "CentOS 5.3(64-bit) no GUI (Simulator)", + "passwordenabled":false,"serviceofferingid":7, + "serviceofferingname":"Small Instance","cpunumber":1, + "cpuspeed":500,"memory":512,"guestosid":11, + "rootdeviceid":0,"rootdevicetype":"NetworkFilesystem", + "securitygroup":[{"id":1,"name":"default", + "description":"Default Security Group"}], + "nic":[{"id":43,"networkid":204, + "netmask":"255.255.255.0","gateway":"192.168.1.1", + "ipaddress":"192.168.1.27", + "isolationuri":"ec2://untagged", + "broadcasturi":"vlan://untagged", + "traffictype":"Guest","type":"Direct", + "isdefault":true,"macaddress":"06:56:b8:00:00:53"}], + "hypervisor":"Simulator" + } + } + } +}''' + + result = '''{ + "queryasyncjobresultresponse" : { + "accountid":"30910093-22e4-4d3c-a464-8b36b60c8001", + "userid":"cb0aeca3-42ee-47c4-838a-2cd9053441f2", + "cmd":"com.cloud.api.commands.DeployVMCmd","jobstatus":1, + "jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object", + "jobresult":{ + "virtualmachine":{ + "id":"d2e4d724-e089-4e59-be8e-647674059016", + "name":"i-2-14-TEST","displayname":"i-2-14-TEST", + "account":"admin", + "domainid":"8cfafe79-81eb-445e-8608-c5b7c31fc3a5", + "domain":"ROOT","created":"2012-01-15T18:30:11+0530", + "state":"Running","haenable":false, + "zoneid":"30a397e2-1c85-40c0-8463-70278952b046", + "zonename":"Sandbox-simulator", + "hostid":"cc0105aa-a2a9-427a-8ad7-4d835483b8a9", + "hostname": + "SimulatedAgent.9fee20cc-95ca-48b1-8268-5513d6e83a1b", + "templateid":"d92570fa-bf40-44db-9dff-45cc7042604d", + "templatename":"CentOS 5.3(64-bit) no GUI (Simulator)", + "templatedisplaytext":"CentOS 5.3(64-bit) no GUI (Simulator)", + "passwordenabled":false, + "serviceofferingid":"3734d632-797b-4f1d-ac62-33f9cf70d005", + "serviceofferingname":"Sample SO","cpunumber":1,"cpuspeed":100, + "memory":128, + "guestosid":"1e36f523-23e5-4e90-869b-a1b5e9ba674d", + "rootdeviceid":0,"rootdevicetype":"NetworkFilesystem", + "nic":[{"id":"4d3ab903-f511-4dab-8a6d-c2a3b51de7e0", + "networkid":"faeb7f24-a4b9-447d-bec6-c4956c4ab0f6", + "netmask":"255.255.240.0","gateway":"10.6.240.1",' + "ipaddress":"10.6.253.89","isolationuri":"vlan://211", + "broadcasturi":"vlan://211","traffictype":"Guest", + "type":"Isolated","isdefault":true, + "macaddress":"02:00:04:74:00:09"}], + "hypervisor":"Simulator" + } + }, + "created":"2012-01-15T18:30:11+0530", + "jobid":"f4a13f28-fcd6-4d7f-b9cd-ba7eb5a5701f" + } +}''' + vm = getResultObj(result, + deployVirtualMachine.deployVirtualMachineResponse()) print vm.jobresult.id - + cmd = deployVirtualMachine.deployVirtualMachineCmd() responsename = cmd.__class__.__name__.replace("Cmd", "Response") response = getclassFromName(cmd, responsename)