Skip to content

Instantly share code, notes, and snippets.

@runiq
Created November 10, 2013 17:35
Show Gist options
  • Save runiq/7401265 to your computer and use it in GitHub Desktop.
Save runiq/7401265 to your computer and use it in GitHub Desktop.
check_sr_modified_patrice.py
#!/usr/bin/env python
"""
Check XenServer SR utilization.
(C) Copyright Pekka Panula/Sofor Oy
Licence: GPLv2 or later
Author: Pekka Panula, E-Mail: [email protected]
Contact if bugs, etc.
- Uses HTTPS to connect to XenServer; if you have a pool, use a
poolmaster IP/FQDN
- <sr name> is case sensitive
- Uses (python) Xen API: Download it from Citrix
(http://community.citrix.com/display/xs/download+sdks)
- Requires Python 2.6
Example: ./check_sr.py 192.168.0.1 root password mysr 90 95
nagios command definition:
define command {
command_name check_xenserver_sr
command_line $user1$/check_sr.py $arg1$ "$user15$" "$user16$" "$arg2$" $arg3$ $arg4$
}
user16 and user15 are username and password in resource.cfg
"""
# TODO:
# - Anpassen der Nagios Command Definition an den veränderten
# Programmaufruf (siehe check_sr_modified.py --help)
from __future__ import division
import argparse, getpass, sys, atexit
import xenapi
def logout():
try:
session.xenapi.session.logout()
except:
# WTF is this, please never do an empty except clause. Instead,
# fail LOUDLY and complain to no end, or your admin will scold
# you.
pass
def humanize_bytes(bytes, precision=2, addsuffix=True, format="pnp4nagios"):
"""
Makes byte numbers human readable by adding k/M/G/T/P prefixes.
"""
if format == "pnp4nagios":
abbrevs = (
(1<<30L, 'Gb'),
(1<<20L, 'Mb'),
(1<<10L, 'kb'),
(1, 'b')
)
else:
abbrevs = (
(1<<50L, 'P'),
(1<<40L, 'T'),
(1<<30L, 'G'),
(1<<20L, 'M'),
(1<<10L, 'k'),
(1, 'b')
)
if bytes == 1:
return '1 b'
for factor, suffix in abbrevs:
if bytes >= factor:
break
suffix = suffix if addsuffix else ''
return "{num:.{precision}f}{suffix}".format(
num=bytes/factor,
precision=precision,
suffix=suffix)
def format_perf_data(s, total, alloc, warning, critical, performancedata_format="pnp4nagios"):
if performancedata_format == 'pnp4nagios':
performance_line = "'{s}_used_space'={alloc};{warning};{critical};0.00;{total}"
else:
performance_line = "size={total}B used={alloc}B;{warning};{critical};0;{total}"
return performance_line.format(s=s,
alloc=str(alloc).replace('.', ','),
warning=str(warning).replace('.', ','),
critical=str(critical).replace('.', ','),
total=str(total).replace('.', ','))
def parse_args():
"""
Parses command-line arguments and returns them in a namespace.
"""
p = argparse.ArgumentParser(formatter=argparse.RawTextHelpFormatter,
description=__doc__)
p.add_argument("url", metavar="URL", help="XenServer IP or FQDN")
p.add_argument("user", metavar="USER", default=getpass.getuser(),
help="User name (default: current user name)")
p.add_argument("password", metavar="PASSWORD", default=None,
help"Password")
p.add_argument("warning", help="Warning level percentage")
p.add_argument("critical", help="Critical level percentage")
p.add_argument("-i", "--info", default="", help="Information to add to the format string")
p.add_argument("-f", "--format",
choices=['pnp4nagios', 'centreon', 'other'],
default='png4nagios', help="Format for performance data string")
return p.parse_args()
def main(session, info, warning, critical, performancedata_format):
gb_factor= 1024**3
mb_factor= 1024**2
srs = session.xenapi.SR.get_all()
for s in srs:
if (session.xenapi.SR.get_type(s) == 'lvm'):
ids = session.xenapi.SR.get_uuid(s)
sr = session.xenapi.SR.get_by_uuid(ids)
sr_pbd = session.xenapi.SR.get_PBDs(sr)
sr_host = session.xenapi.PBD.get_host(sr_pbd[0])
server_name = session.xenapi.host.get_name_label(sr_host)
sr_size = session.xenapi.SR.get_physical_size(sr)
sr_phys_util = session.xenapi.SR.get_physical_utilisation(sr)
sr_virtual_alloc = session.xenapi.SR.get_virtual_allocation(sr)
total_bytes_gb = int(sr_size) / gb_factor
total_bytes_mb = int(sr_size) / mb_factor
total_bytes_b = int(sr_size)
total_alloc_gb = int(sr_phys_util) / gb_factor
total_alloc_mb = int(sr_phys_util) / mb_factor
total_alloc_b = int(sr_phys_util)
virtual_alloc_gb = int(sr_virtual_alloc) / gb_factor
virtual_alloc_mb = int(sr_virtual_alloc) / mb_factor
free_space = int(total_bytes_gb) - int(total_alloc_gb)
free_space_b = int(total_bytes_b) - int(total_alloc_b)
used_percent = 100*float(total_alloc_gb)/float(total_bytes_gb)
warning_gb = (float(total_bytes_gb) / 100) * float(warning)
warning_mb = (float(total_bytes_mb) / 100) * float(warning)
warning_b = int((int(total_bytes_b) / 100) * float(warning))
critical_gb = (float(total_bytes_gb) / 100) * float(critical)
critical_mb = (float(total_bytes_mb) / 100) * float(critical)
critical_b = int((float(total_bytes_b) / 100) * float(critical))
if performancedata_format == "pnp4nagios":
performance = format_perf_data(ids,
humanize_bytes(total_bytes_b, precision=1, suffix=False, format=performancedata_format),
humanize_bytes(total_alloc_b, precision=1, format=performancedata_format),
humanize_bytes(warning_b, precision=1, suffix=False, format=performancedata_format),
humanize_bytes(critical_b, precision=1, suffix=False, format=performancedata_format),
performancedata_format)
else:
performance = format_perf_data(ids, total_bytes_b, total_alloc_b,
warning_b, critical_b, performancedata_format)
info = "on %s: utilization %s%%, size %s, used %s, free %s | %s" % ((server_name),
str(round(used_percent,2)),
str(humanize_bytes(total_bytes_b, precision=0)),
str(humanize_bytes(total_alloc_b, precision=0)),
str(humanize_bytes(free_space_b, precision=0)),
performance)
if float(used_percent) >= float(critical):
print "CRITICAL: SR-ID", ids, info
exitcode = 2
break
elif float(used_percent) >= float(warning):
print "WARNING: SR-ID", ids, info
exitcode = 1
break
else:
print "OK: All SR's are in a OK state"
exitcode = 0
#print "SR Physical size:" , str(humanize_bytes(total_bytes_b, precision=1))
#print "SR Virtual allocation:" , str(humanize_bytes(int(sr_virtual_alloc), precision=1))
#print "SR Physical Utilization:", str(humanize_bytes(total_alloc_b, precision=1))
#print "SR Free space:", str(humanize_bytes(free_space_b, precision=1))
#print "SR Space used:", str(round(used_percent,2)), "%"
#print "SR Warning level:", str(humanize_bytes(warning_b, precision=1))
#print "SR Critical level:", str(humanize_bytes(critical_b, precision=1))
sys.exit(exitcode)
if __name__ == "__main__":
args = parse_args()
# Always log out on program exit
atexit.register(logout)
# First acquire a valid session by logging in:
try:
session = XenAPI.Session("https://" + args.url)
except Exception, e:
print "CRITICAL: Can't get XenServer session, error: ", str(e)
sys.exit(2)
# Then try to actually log in:
if args.password is None:
try:
password = getpass.getpass("XenServer password for " + args.user)
except getpass.GetPassWarning:
print "Caution, the password may be echoed to the terminal."
else:
print "Caution: Giving your password as an argument to this script is a security risk, as it can be seen on process monitoring tools such as ps."
try:
session.xenapi.login_with_password(args.user, password)
except Exception, e:
print "CRITICAL: Can't login to XenServer, error: ", str(e)
sys.exit(2)
main(session=session,
info=args.info,
warning=args.warning,
critical=args.critical,
performancedata_format=args.format)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment