Skip to content

Instantly share code, notes, and snippets.

@cluther
Created October 23, 2014 18:44
Show Gist options
  • Select an option

  • Save cluther/cd400c1162bdec0b02f4 to your computer and use it in GitHub Desktop.

Select an option

Save cluther/cd400c1162bdec0b02f4 to your computer and use it in GitHub Desktop.
Zenoss: Custom XML Export
# It is expected that the following code would be placed in the
# __init__.py of your ZenPack.
# lxml provides an API for building XML documents.
# http://lxml.de/tutorial.html#the-e-factory
from lxml import etree
from lxml.builder import E
# monkeypatch allows us to add a new method (myXML) to an existing
# object (ZentinelPortal a.k.a. /zport).
from Products.ZenUtils.Utils import monkeypatch
# getFacade allows access to the high-level Zenoss Python API.
from Products.Zuul import getFacade
@monkeypatch('Products.ZenModel.ZentinelPortal.ZentinelPortal')
def myXML(self, service_uid=None):
"""Return XML.
Example service_uid:
/zport/dmd/DynamicServices/Tenants/ACME/services/ACME
It is expected that this method be called via an HTTP GET to a URL
like the following:
http://myzenoss:8080/zport/myXML?service_uid=/zport/dmd/DynamicServices/Tenants/ACME/services/ACME
Assumes a nested service structure something like the following:
ACME
|
+-- ACME-Org1
| |
| +-- ACME-Org1-VDC1
| | |
| | +-- VM1
| | +-- VM2
| |
| +-- ACME-Org1-VDC2
|
+-- ACME-Org2
|
+-- ACME-Org2-VDC1
Returns an XML document something like the following:
<?xml version='1.0' encoding='utf-8'?>
<service availability="UP" name="ACME" performance="ACCEPTABLE">
<subservices>
<service availability="UP" name="ACME-Org1" performance="ACCEPTABLE">
<subservices>
<service availability="UP" name="ACME-Org1-VDC2" performance="ACCEPTABLE">
<subservices/>
<vms/>
</service>
<service availability="UP" name="ACME-Org1-VDC1" performance="ACCEPTABLE">
<subservices/>
<vms>
<vm availability="UP" memory="1073741824" name="app-server-a" osType="CentOS 4/5/6 (64-bit)" performance="ACCEPTABLE" storage="9562423296" vcpus="1"/>
<vm availability="UP" memory="536870912" name="web-server-a" osType="CentOS 4/5/6 (64-bit)" performance="ACCEPTABLE" storage="9561972736" vcpus="1"/>
</vms>
</service>
</subservices>
<vms/>
</service>
</subservices>
<vms/>
</service>
"""
if not service_uid:
return xml_string(xml_error("missing 'service_uid' request parameter"))
return etree.tostring(
xml_for_service(service_uid),
encoding='utf-8',
xml_declaration=True)
def xml_for_service(service_uid):
"""Return XML for service_uid."""
# Get a handle to the Impact (enterpriseservices) facade.
impact = getFacade('enterpriseservices')
# Get info for the specified service.
try:
service_info = impact.getInfo(service_uid)
except Exception as e:
return xml_error(str(e))
# Start XML document with top-level service information.
subservices = E.subservices()
vms = E.vms()
xml = E.service(
subservices,
vms,
name=service_info.name,
availability=service_info.availability(),
performance=service_info.performance())
# Get dependencies for the specified service.
service_dependencies = impact.getDependencies(service_uid)
for service_dependency in service_dependencies:
if service_dependency.type == 'DynamicService':
subservices.append(xml_for_service(service_dependency.url))
elif service_dependency.type == 'vSphereVirtualMachine':
vms.append(xml_for_vm(service_dependency))
return xml
def xml_for_vm(service_dependency):
"""Return XML for VM service_dependency."""
device_facade = getFacade('device')
vm = device_facade.getInfo(service_dependency.url)
return E.vm(
name=vm.name,
availability=service_dependency.state['AVAILABILITY'],
performance=service_dependency.state['PERFORMANCE'],
vcpus=str(vm.numCPU),
memory=str(vm.memory),
storage=str(vm.storageUncommitted),
osType=vm.osType)
def xml_string(xml):
"""Return a string representation of xml object."""
return etree.tostring(xml, encoding='utf-8', xml_declaration=True)
def xml_error(message):
"""Return XML string with error message."""
return E.error(E.message(message))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment