document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. #!/usr/bin/python
  2.  
  3. \'\'\'
  4. check_rss v .35 - A simple Nagios plugin to check an RSS feed. Created to monitor status of cloud services.
  5.  
  6. Requires feedparser and argparse python libraries. For Ubuntu you can install with "sudo apt-get install python-feedparser python-argparse"
  7. If you find it useful, feel free to leave me a comment/email at http://john.wesorick.com.
  8.  
  9.  
  10. Copyright 2011 John Wesorick (john.wesorick.com)
  11.  
  12. This program is free software: you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation, either version 3 of the License, or
  15. (at your option) any later version.
  16.  
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. GNU General Public License for more details.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  24. \'\'\'
  25.  
  26. import feedparser
  27. import argparse
  28. import sys
  29. import datetime
  30.  
  31.  
  32. def main(argv=None):
  33.     # Set up our arguments
  34.     try:
  35.         parser = argparse.ArgumentParser(description="check_rss v0.35 - A simple Nagios plugin to check an RSS feed. Created to monitor status of cloud services. ", epilog="notes: If you do not specify any warning or critical conditions, it will always return OK. This will only check the newest feed entry. Copyright 2011 John Wesorick (http://john.wesorick.com)")
  36.         parser.add_argument(\'-H\', dest=\'rssfeed\', help=\'URL of RSS feed to monitor\', action=\'store\', required=True)
  37.         parser.add_argument(\'-c\', \'--criticalif\', dest=\'criticalif\', help=\'Comma separated, quoted list of strings that will result in critical condition if PRESENT\', action=\'store\')
  38.         parser.add_argument(\'-C\', \'--criticalnot\', dest=\'criticalnot\', help=\'Comma separated, quoted list of strings that will result in critical condition if MISSING\', action=\'store\')
  39.         parser.add_argument(\'-w\', \'--warningif\', dest=\'warningif\', help=\'Comma separated, quoted list of strings that will result in warning condition if PRESENT\', action=\'store\')
  40.         parser.add_argument(\'-W\', \'--warningnot\', dest=\'warningnot\', help=\'Comma separated, quoted list of strings that will result in warning condition if MISSING\', action=\'store\')
  41.         parser.add_argument(\'-T\', \'--hours\', dest=\'hours\', help=\'Hours since last post. Will return critical if less than designated amount.\', action=\'store\')
  42.         parser.add_argument(\'-t\', \'--titleonly\', dest=\'titleonly\', help=\'Search the titles only. The default is to search for strings matching in either the title or description\', action=\'store_true\', default=False)
  43.         parser.add_argument(\'-p\', \'--perfdata\', dest=\'perfdata\', help=\'If used will keep very basic performance data (0 if OK, 1 if WARNING, 2 if CRITICAL, 3 if UNKNOWN)\', action=\'store_true\', default=False)
  44.         parser.add_argument(\'-v\', \'--verbosity\', dest=\'verbosity\', help=\'Verbosity level. 0 = Only the title and time is returned. 1 = Title, time and link are returned. 2 = Title, time, link and description are returned (Default)\', action=\'store\', default=\'2\')
  45.         args = parser.parse_args()
  46.     except:
  47.         # Something didn\'t work. We will return an unknown.
  48.         output = \': Invalid argument(s) {usage}\'.format(usage=parser.format_usage())
  49.         exitunknown(output)
  50.  
  51.     perfdata = args.perfdata
  52.  
  53.     # Parse our feed, getting title, description and link of newest entry.
  54.     rssfeed = args.rssfeed
  55.     if ( rssfeed.find(\'http://\') != 0 ):
  56.         rssfeed = \'http://{rssfeed}\'.format(rssfeed=rssfeed)
  57.     try:
  58.         myfeed = feedparser.parse(rssfeed)
  59.         feednumber = 0 #Grabs only the newest entry.
  60.         title = myfeed[\'entries\'][feednumber][\'title\']
  61.         description = myfeed[\'entries\'][feednumber][\'description\']
  62.         link = myfeed[\'entries\'][feednumber][\'link\']
  63.         feeddate = myfeed[\'entries\'][feednumber][\'updated_parsed\']
  64.     except:
  65.         output = \': Could not parse URL ({rssfeed})\'.format(rssfeed=rssfeed)
  66.         exitcritical(output, perfdata)
  67.    
  68.     # Get the difference in time from last post
  69.     now = datetime.datetime.now()
  70.     orderedfeeddate = datetime.datetime(feeddate.tm_year, feeddate.tm_mon, feeddate.tm_mday, feeddate.tm_hour, feeddate.tm_min)
  71.     orderednowdate = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute)
  72.     timediff = orderednowdate - orderedfeeddate
  73.     hourssinceposted = timediff.days * 24 + timediff.seconds / 60 / 60
  74.        
  75.     # We will form our response here based on the verbosity levels. This makes the logic below a lot easier.
  76.     if (args.verbosity == \'0\' ):
  77.         output = \': Posted {hourssinceposted} hrs ago ; {title}\'.format(hourssinceposted=hourssinceposted, title=title.encode(\'utf-8\'))
  78.     elif (args.verbosity == \'1\' ):
  79.         output = \': Posted {hourssinceposted} hrs ago ; Title: {title} ; Link: {link}\'.format(hourssinceposted=hourssinceposted, title=title.encode(\'utf-8\'), link=link)
  80.     elif (args.verbosity == \'2\' ):
  81.         output = \': Posted {hourssinceposted} hrs ago ; Title: {title} ; Description: {description} ; Link: {link}\'.format(hourssinceposted=hourssinceposted, title=title.encode(\'utf-8\'), description=description.encode(\'utf-8\'), link=link)
  82.  
  83.     # Check for strings that match, resulting in critical status
  84.     if ( args.criticalif ):
  85.         criticalif = args.criticalif.lower().split(\',\')
  86.         for search in criticalif:
  87.             if ( args.titleonly == True ):
  88.                 if ( title.lower().find(search) >= 0 ):
  89.                     exitcritical(output, perfdata)
  90.             else:
  91.                 if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
  92.                     exitcritical(output, perfdata)
  93.  
  94.     # Check for strings that are missing, resulting in critical status
  95.     if ( args.criticalnot ):
  96.         stringmatched = False
  97.         criticalnot = args.criticalnot.lower().split(\',\')
  98.         for search in criticalnot:
  99.             if ( args.titleonly == True ):
  100.                 if ( title.lower().find(search) >= 0 ):
  101.                     stringmatched = True
  102.                     break
  103.             else:
  104.                 if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
  105.                     stringmatched = True
  106.                     break
  107.         if not stringmatched:
  108.             print description.lower()
  109.             exitcritical(output, perfdata)
  110.                    
  111.     # Check for time difference (in hours), resulting in critical status
  112.     if ( args.hours ):
  113.         if ( int(hourssinceposted) <= int(args.hours) ):
  114.             exitcritical(output, perfdata)
  115.    
  116.     # Check for strings that match, resulting in warning status
  117.     if ( args.warningif ):
  118.         warningif = args.warningif.lower().split(\',\')
  119.         for search in warningif:
  120.             if ( args.titleonly == True ):
  121.                 if ( title.lower().find(search) >= 0 ):
  122.                     exitwarning(output, perfdata)
  123.             else:
  124.                 if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
  125.                     exitwarning(output, perfdata)
  126.  
  127.     # Check for strings that are missing, resulting in warning status
  128.     if ( args.warningnot ):
  129.         stringmatched = False
  130.         warningnot = args.warningnot.lower().split(\',\')
  131.         for search in criticalnot:
  132.             if ( args.titleonly == True ):
  133.                 if ( title.lower().find(search) >= 0 ):
  134.                     stringmatched = True
  135.                     break
  136.             else:
  137.                 if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
  138.                     stringmatched = True
  139.                     break
  140.         if not stringmatched:
  141.             print description.lower()
  142.             exitwarning(output, perfdata)
  143.            
  144.     # If we made it this far, we must be ok
  145.     exitok(output, perfdata)
  146.  
  147. def exitok(output, perfdata):
  148.     if ( perfdata ):
  149.         print "OK{output}|\'RSS\'=0;1;2;0;2".format(output=output)
  150.     else:
  151.         print \'OK{output}\'.format(output=output)
  152.     sys.exit(0)
  153.  
  154. def exitwarning(output, perfdata):
  155.     if ( perfdata ):
  156.         print "WARNING{output}|\'RSS\'=1;1;2;0;2".format(output=output)
  157.     else:
  158.         print \'WARNING{output}\'.format(output=output)
  159.     sys.exit(1)
  160.  
  161. def exitcritical(output, perfdata):
  162.     if ( perfdata ):
  163.         print "CRITICAL{output}|\'RSS\'=2;1;2;0;2".format(output=output)
  164.     else:
  165.         print \'CRITICAL{output}\'.format(output=output)
  166.     sys.exit(2)
  167.  
  168. def exitunknown(output):
  169.     sys.exit(3)
  170.  
  171. if __name__ == \'__main__\':
  172.     result = main(sys.argv)
  173.     sys.exit(result)
');