Created
November 10, 2013 17:35
-
-
Save runiq/7401265 to your computer and use it in GitHub Desktop.
check_sr_modified_patrice.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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