Skip to content

Commit

Permalink
Refactor the way we retrieve host and datastore properties
Browse files Browse the repository at this point in the history
  • Loading branch information
dnaeon committed Oct 15, 2013
1 parent 9e98f48 commit 0a19763
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/vmpoller-client
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def main():
Usage:
vmpoller-client [-r <retries>] [-t <timeout>] [-l <logfile>] (-D|-H) -c discover -V <vcenter> -e <endpoint>
vmpoller-client [-r <retries>] [-t <timeout>] [-l <logfile>] -H -n <name> -p <property> -c poll -V <vcenter> -e <endpoint>
vmpoller-client [-r <retries>] [-t <timeout>] [-l <logfile>] -D -n <name> -p <property> -u <datastore-url> -c poll -V <vcenter> -e <endpoint>
vmpoller-client [-r <retries>] [-t <timeout>] [-l <logfile>] -D -u <datastore-url> -p <property> -c poll -V <vcenter> -e <endpoint>
vmpoller-client --help
vmpoller-client --version
Expand All @@ -53,7 +53,7 @@ Options:
-H, --hosts Retrieve a host object property
-V <vcenter>, --vcenter <vcenter> The vCenter server to send the request to
-c <cmd>, --command <cmd> The command to perform, either "poll" or "discover"
-n <name>, --name <name> Name of the object, e.g. datastore/host name
-n <name>, --name <name> Name of the ESX host, only applicable to hosts object type
-p <property>, --property <property> Name of the property as defined by the vSphere Web SDK
-u <datastore-url>, --url <datastore-url> Datastore URL, only applicable to datastores object type
-r <retries>, --retries <retries> Number of time to retry if a request times out [default: 3]
Expand All @@ -80,7 +80,7 @@ Options:
msg = { "type": "hosts" if args["--hosts"] else "datastores",
"vcenter": args["--vcenter"],
"name": args["--name"],
"ds_url": args["--url"],
"info.url": args["--url"],
"cmd": args["--command"],
"property": args["--property"],
}
Expand Down
42 changes: 19 additions & 23 deletions src/vmpoller/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
import json
import logging
import ConfigParser
from time import sleep, asctime
from time import asctime, strftime

import zmq
from vmconnector.core import VMConnector
Expand Down Expand Up @@ -416,8 +416,8 @@ def get_host_property(self, msg):
if not self.viserver.is_connected():
self.reconnect()

# Search is done by using the 'name' property of the ESX Host
# Properties we want to retrieve are 'name' and the requested property
# Search is done by using the 'name' property of the ESX Host as
# this uniquely identifies the host
#
# Check the vSphere Web Services SDK API for more information on the properties
#
Expand All @@ -434,7 +434,7 @@ def get_host_property(self, msg):
'runtime.inMaintenanceMode': lambda p: int(p), # The value we return is integer
'summary.config.vmotionEnabled': lambda p: int(p), # The value we return is integer
'summary.rebootRequired': lambda p: int(p), # The value we return is integer
'runtime.bootTime': lambda p: time.strftime('%Y-%m-%d %H:%M:%S', p),
'runtime.bootTime': lambda p: strftime('%Y-%m-%d %H:%M:%S', p),
}

logging.info('[%s] Retrieving %s for host %s', self.vcenter, msg['property'], msg['name'])
Expand All @@ -444,7 +444,6 @@ def get_host_property(self, msg):
results = self.viserver._retrieve_properties_traversal(property_names=property_names,
obj_type=MORTypes.HostSystem)
except Exception as e:
sleep(1) # Settle down for a moment
logging.warning("Cannot get property for host %s: %s", msg["name"], e)
return "Cannot get property for host %s: %s" % (msg["name"], e)

Expand Down Expand Up @@ -480,8 +479,7 @@ def get_datastore_property(self, msg):
msg = { "type": "datastores",
"vcenter": "sof-vc0-mnik",
"name": "datastore1",
"ds_url": "ds:///vmfs/volumes/5190e2a7-d2b7c58e-b1e2-90b11c29079d/",
"info.url": "ds:///vmfs/volumes/5190e2a7-d2b7c58e-b1e2-90b11c29079d/",
"property": "summary.capacity"
}
Expand All @@ -493,26 +491,27 @@ def get_datastore_property(self, msg):
"""
# Sanity check for required attributes in the message
if not all(k in msg for k in ("type", "vcenter", "name", "ds_url", "property")):
return "Missing message properties (e.g. vcenter/ds_url)"
if not all(k in msg for k in ("type", "vcenter", "info.url", "property")):
return "Missing message properties (e.g. vcenter/info.url)"

# Check if we are connected first
if not self.viserver.is_connected():
self.reconnect()

# Search is done by using the 'info.name' and 'info.url' properties
# Search is done by using the 'info.url' property as
# this uniquely identifies the datastore
#
# Check the vSphere Web Services SDK API for more information on the properties
#
# https://www.vmware.com/support/developer/vc-sdk/
#
property_names = ['info.name', 'info.url', msg['property']]
property_names = ['info.url', msg['property']]

# Custom properties, which are not available in the vSphere Web SDK
# Keys are the property names and values are a list/tuple of the properties required to
# calculate the custom properties
custom_zbx_properties = {
'ds_used_space_percentage': ('summary.freeSpace', 'summary.capacity')
'ds_used_space_percentage': ['summary.freeSpace', 'summary.capacity']
}

# Some of the properties we process need to be converted to a Zabbix-friendly value
Expand All @@ -528,36 +527,35 @@ def get_datastore_property(self, msg):
property_names.extend(custom_zbx_properties[msg["property"]])
property_names.remove(msg["property"])

logging.info('[%s] Retrieving %s for datastore %s', self.vcenter, msg['property'], msg['name'])
logging.info('[%s] Retrieving %s for datastore %s', self.vcenter, msg['property'], msg['info.url'])

try:
results = self.viserver._retrieve_properties_traversal(property_names=property_names,
obj_type=MORTypes.Datastore)
except Exception as e:
sleep(1) # Settle down for a moment
logging.warning("Cannot get property for datastore %s: %s" % (msg["name"], e))
return "Cannot get property for datastore %s: %s" % (msg["name"], e)
logging.warning("Cannot get property for datastore %s: %s" % (msg["info.url"], e))
return "Cannot get property for datastore %s: %s" % (msg["info.url"], e)

if not results:
return "Did not find property %s for datastore %s" % (msg["property"], msg["name"])
return "Did not find property %s for datastore %s" % (msg["property"], msg["info.url"])

# Iterate over the results and find our datastore with 'info.name' and 'info.url' properties
# Iterate over the results and find our datastore
for item in results:
props = [(p.Name, p.Val) for p in item.PropSet]
d = dict(props)

# break if we have a match
if d['info.name'] == msg['name'] and d['info.url'] == msg['ds_url']:
if d['info.url'] == msg['info.url']:
break
else:
return "Unable to find datastore %s" % msg["name"]
return "Unable to find datastore %s" % msg["info.url"]

# Do we need to convert this value to a Zabbix-friendly one?
if msg["property"] in zbx_helpers:
val = zbx_helpers[msg["property"]](d)
else:
# No need to convert anything
val = d[msg["property"]] if d.get(msg["property"]) else 0 # Make sure we've got the property
val = d[msg["property"]] if d.get(msg["property"]) else 0

return val

Expand Down Expand Up @@ -592,7 +590,6 @@ def discover_hosts(self):
results = self.viserver._retrieve_properties_traversal(property_names=property_names,
obj_type=MORTypes.HostSystem)
except Exception as e:
sleep(1) # Settle down for a moment
logging.warning("Cannot discover hosts: %s", e)
return "Cannot discover hosts: %s" % e

Expand Down Expand Up @@ -645,7 +642,6 @@ def discover_datastores(self):
results = self.viserver._retrieve_properties_traversal(property_names=property_names,
obj_type=MORTypes.Datastore)
except Exception as e:
sleep(1) # Settle down for a moment
logging.warning("Cannot discover datastores: %s", e)
return "Cannot discover datastores: %s" % e

Expand Down

0 comments on commit 0a19763

Please sign in to comment.