#!/usr/bin/python ########################################################################## # Copyright (C) 2018 Igor Castro # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see ########################################################################### ########################################################################### # Version = 1.0 # Organisation = IATA # Author = I.CASTRO # Description = File monitoring for backup # # ########################################################################## import os, sys, time, argparse, datetime from datetime import date # Hardcoded parameters to debug my_command="ls -qalt" # exit statuses recognized by Nagios OK = 0 WARNING = 1 CRITICAL = 2 UNKNOWN = 3 # Create a Parser to get value from command arguments parser = argparse.ArgumentParser(description="Nagios check to validate if there is new backup received within defined threshold and optionally validate corruption via checksum can be run like ./check_file_monitoring -d '/home/user/' -f '*.crt' can be also executed remotely via check_by_ssh") parser.add_argument('-c', default=30, dest='critical', type=int, help='critical threshold in day for nagios (default: 30) is number of days without newer backup received') parser.add_argument('-w', default=15, dest='warning', type=int, help='warning threshold in day for nagios for nagios (default: 15) is number of days without newer backup received') parser.add_argument('-f', dest='file_check', help='file pattern to be found in backup file name') parser.add_argument('-d', dest='dir_check', help='directory to look for the files') parser.add_argument('-s', default='none', dest='crc', help='Optionally looks for latest file name with checksum to validate transfer integrity currently only default none or md5 are implemented file.md5 must be available') args = parser.parse_args() warning_arg=args.warning critical_arg=args.critical file_check=args.file_check dir_check=args.dir_check crc=args.crc # # Create the actual command with all parameters full_command="%s %s%s" % (my_command,dir_check,file_check) # Send the command to the OS result_command=os.popen(full_command) # Save result in a proper array result=result_command.readlines() # Save number of lines detected in result nb_lines= int(len(result)) # If there are no lines something is wrong` if nb_lines > 0 : # Get latest modified file matching pattern and extract corresponding date # Format is permission,user id, user, group, size, month, day, year, file last=result[0].split() #Check if ls output is displaying hour instead of year we must replace it by current year if (last[7].find(':') != -1): last[7]= datetime.datetime.today().year #print "last %s" % (last) # Create a date with values extracted and converted in integer last_date=date(int(last[7]),datetime.datetime.strptime(last[5], '%b').month,int(last[6])) #calculate current today value in days today = date.today() remaining_day = today - last_date #print"last date %s today date %s remaining days %s" % (last_date,today,remaining_day) # Check if the size of the file is not null if last[4] < 1 : print "CRITICAL - Last file found %s was updated on %s but has an anbormal size of %s KiBs " %(last[8],last_date,last[4]) sys.exit(CRITICAL) else : # Check if the remaining number of days is more than critical threshold if remaining_day.days > critical_arg : print "CRITICAL - Last file found %s was updated on %s which is more than critical threshold of %d days old" %(last[8],last_date,critical_arg) sys.exit(CRITICAL) else : # Check if the remaining number of days is more than warning threshold if remaining_day.days > warning_arg : print "WARNING - Last file found %s was updated on %s which is more than warning threshold of %d days old" %(last[8],last_date,warning_arg) sys.exit(WARNING) else : # Check if CRC option was used if crc.find('md5') != -1: #CRC option md5 is used check_crc_file= last[8] + "." + crc my_command="md5sum" #Execute md5sum remotely result_command=os.popen(my_command + " " + last[8]) # Save result first line result_crc=result_command.readline() result_crc=result_crc.split() #Read checksum more received checksum file result_command=os.popen("cat " + check_crc_file) # Save result first line received_crc =result_command.readline() received_crc = received_crc.split() #Validate that checksum calculated is inside of crc file received if result_crc[0].find(received_crc[0]) != -1: print "OK - Last file found %s was updated on %s , has a size of %s KiBs and has a valid %s calculated of %s wich matches the one received in %s" % (last[8],last_date,last[4],crc,result_crc[0],check_crc_file) sys.exit(OK) else : print "CRITICAL - Last file found %s has %s of %s which is different than the one received in % of %s" % (last[8],crc,result_crc[0],check_crc_file,received_crc[0]) sys.exit(CRITICAL) else : print "OK - Last file found %s was updated on %s and has a size of %s KiBs " % (last[8],last_date,last[4]) sys.exit(OK) else : sys.exit(UNKNOWN)