cloudstack/tools/marvin/marvin/jsonHelper.py

390 lines
14 KiB
Python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# 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
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import cloudstackException
import json
import inspect
from marvin.cloudstackAPI import *
class jsonLoader(object):
'''The recursive class for building and representing objects with.'''
def __init__(self, obj):
for k in obj:
v = obj[k]
if isinstance(v, dict):
setattr(self, k, jsonLoader(v))
elif isinstance(v, (list, tuple)):
if len(v) > 0 and isinstance(v[0], dict):
setattr(self, k, [jsonLoader(elem) for elem in v])
else:
setattr(self, k, v)
else:
setattr(self, k, v)
def __getattr__(self, val):
if val in self.__dict__:
return self.__dict__[val]
else:
return None
def __getitem__(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()))
def __str__(self):
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
in self.__dict__.iteritems()))
class jsonDump(object):
@staticmethod
def __serialize(obj):
"""Recursively walk object's hierarchy."""
if isinstance(obj, (bool, int, long, float, basestring)):
return obj
elif isinstance(obj, dict):
obj = obj.copy()
newobj = {}
for key in obj:
if obj[key] is not None:
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]
elif isinstance(obj, tuple):
return tuple(jsonDump.__serialize([item for item in obj]))
elif hasattr(obj, '__dict__'):
return jsonDump.__serialize(obj.__dict__)
else:
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):
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
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():
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():
if k in responsecls.__dict__:
findObj = True
break
if findObj:
return value
else:
return result
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]
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)
respname = responseName.replace("response", "")
raise cloudstackException.CloudstackAPIException(respname, errMsg)
if result.count is not None:
for key in result.__dict__.iterkeys():
if key == "count":
continue
else:
return getattr(result, key)
else:
return finalizeResultObj(result, responseName, responsecls)
if __name__ == "__main__":
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" : [ { "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,
"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"
}
}'''
try:
asynJob = getResultObj(result)
except cloudstackException.CloudstackAPIException as 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"
}
}
}'''
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)"
}
}
}'''
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())
print vm.jobresult.id
cmd = deployVirtualMachine.deployVirtualMachineCmd()
responsename = cmd.__class__.__name__.replace("Cmd", "Response")
response = getclassFromName(cmd, responsename)
print response.id