#!/usr/bin/env python import urllib import sys from lxml import etree from optparse import OptionParser, OptionGroup AVAILABLE_CITIES = [ 'California', 'Colorado', 'Florida', 'Massachusetts', 'Minnesota', 'New York', 'Ohio', 'Texas', 'Washington', 'Boston', 'Chicago', 'Cleveland', 'Denver', 'Houston', 'Los Angeles', 'Miami', 'New York City', 'San Francisco', 'Seattle', ] class NagiosReturn(Exception): def __init__(self, message, code): self.message = message self.code = code def parse_args(): global AVAILABLE_CITIES city_string = '\n'.join(AVAILABLE_CITIES) usage = "usage: %prog -L location -w warning -c critical\n\nPossible locations:\n" + city_string parser = OptionParser(usage=usage) required = OptionGroup(parser, "Required Options") required.add_option('-L' , '--location', help='Specify the location', default=None) parser.add_option_group(required) nagios = OptionGroup(parser, "Nagios Plugin Information") nagios.add_option('-w', '--warning', help='Specify warning range.', default=None) nagios.add_option('-c', '--critical', help='Specify critical range.', default=None) parser.add_option_group(nagios) options, _ = parser.parse_args() if not options.location: parser.error('Location is a required option.') if not options.location in AVAILABLE_CITIES: parser.error('Location not in available location. Suitable locations are:') for x in AVAILABLE_CITIES: print x return options def is_within_range(nagstring, value): if not nagstring: return False import re import operator first_float = r'(?P(-?[0-9]+(\.[0-9]+)?))' second_float= r'(?P(-?[0-9]+(\.[0-9]+)?))' actions = [ (r'^%s$' % first_float,lambda y: (value > float(y.group('first'))) or (value < 0)), (r'^%s:$' % first_float,lambda y: value < float(y.group('first'))), (r'^~:%s$' % first_float,lambda y: value > float(y.group('first'))), (r'^%s:%s$' % (first_float,second_float), lambda y: (value < float(y.group('first'))) or (value > float(y.group('second')))), (r'^@%s:%s$' % (first_float,second_float), lambda y: not((value < float(y.group('first'))) or (value > float(y.group('second')))))] for regstr,func in actions: res = re.match(regstr,nagstring) if res: return func(res) raise Exception('Improper warning/critical format.') def main(): options = parse_args() filename, fobject = urllib.urlretrieve("http://www.eia.gov/dnav/pet/pet_pri_gnd_a_epm0_pte_dpgal_w.htm") f = open(filename, 'r') fstr = ''.join(f.readlines()) html = etree.HTML(fstr) gas_list = html.xpath("//text()") index = gas_list.index(options.location) price = float(gas_list[index:index+14][-1]) returnval = NagiosReturn('', 2) if is_within_range(options.critical, price): returnval.message = 'CRITICAL: Gas price is at $%.2f | price=%.2f' % (price, price) returnval.code = 2 elif is_within_range(options.warning, price): returnval.message = 'WARNING: Gas price is at $%.2f | price=%.2f' % (price, price) returnval.code = 1 else: returnval.message = 'OK: Gas price is at $%.2f | price=%.2f' % (price, price) returnval.code = 0 raise returnval if __name__ == '__main__': try: main() except IOError, e: print e sys.exit(3) except NagiosReturn, e: print e.message sys.exit(e.code)