Last active
August 29, 2015 14:03
-
-
Save junaid18183/8d7e6e0388c4152df679 to your computer and use it in GitHub Desktop.
This file contains 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/python | |
#Author: Juned Memon | |
#Base for this script was created by: Andrew McDonald andrew@mcdee.com.au http://mcdee.com.au and Jelle Bekker | |
# Example: config file | |
#[client] | |
#host = localhost | |
#user = root | |
#password = root-pass | |
#For parameter usage, use the -h parameter | |
from datetime import datetime | |
import argparse | |
import os | |
import commands | |
import sys | |
import tarfile | |
import time | |
import pynsca | |
from pynsca import NSCANotifier | |
#------------------------------------------------------------------------------------------------------------ | |
#Nagios NSCA Configuration Details | |
host='localhost' | |
encryption_mode=1 #NSCA encryption_mode | |
monitoring_port=5667 | |
nsca_password="omd-secret" | |
service_name="Check_Backup_"+host | |
#------------------------------------------------------------------------------------------------------------ | |
def is_dir(path): | |
"""Checks if a path is an actual directory""" | |
if not os.path.isdir(path): | |
msg = "{0} is not a directory".format(path) | |
raise argparse.ArgumentTypeError(msg) | |
else: | |
return path | |
def is_file(path): | |
"""Checks if a path is a valid file""" | |
if not os.path.isfile(path): | |
msg = "{0} is not a valid file".format(path) | |
raise argparse.ArgumentTypeError(msg) | |
else: | |
return path | |
def get_args(): | |
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) | |
parser.add_argument('--conf', action='store', type=is_file, required=True, help= | |
("Path to a config file with the following contents:\n" | |
"\n" | |
"[client]\n" | |
"user = [root]\n" | |
"password = [root-pass]\n" | |
"host = [localhost]\n") | |
) | |
parser.add_argument('--backup-directory', type=is_dir, required=True, help='Target directory for the backup') | |
parser.add_argument('--compress', action='store_true', help='Compress the backup files') | |
parser.add_argument('--age', type=int, help='Delete backup files older than the specified amount of days') | |
parser.add_argument('--nagios',help='sends the backup details to this nagios server using NSCA, service name will be Check_Backup_%host%_%db%') | |
parser.add_argument('--dblist', required=True,help='Target databases',nargs='+') | |
return parser.parse_args() | |
def set_permissions(path, permissions=0640): | |
return os.chmod(path, permissions) | |
#def mysql_dblist(cnf): | |
# ignore_db = ['information_schema', 'performance_schema', 'test'] | |
# cmd = ['mysql', '--defaults-extra-file='+cnf, '-se', 'show databases'] | |
# p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
# stdout, stderr = p.communicate() | |
# if p.returncode >0: | |
# print "MySQL Error:" | |
# print stderr | |
# sys.exit(1) | |
# dblist = stdout.strip().split('\n') | |
# for item in ignore_db: | |
# try: | |
# dblist.remove(item) | |
# except ValueError: | |
# continue | |
# if len(dblist) == 0: | |
# print "Doesn't appear to be any user databases found" | |
# return dblist | |
def mysql_backup(dblist, cnf, dir, compress,nagios_host): | |
for db in dblist: | |
bdate = datetime.now().strftime('%Y%m%d%H%M') | |
bfile = db+'_'+bdate+'.sql' | |
fullpath = os.path.join(dir, bfile) | |
if db == 'mysql': | |
cmd = "mysqldump --defaults-extra-file=%s --events %s > %s" %(cnf,db,fullpath) | |
else: | |
cmd = "mysqldump --defaults-extra-file=%s %s > %s" %(cnf,db,fullpath) | |
status, output = commands.getstatusoutput(cmd) | |
if status == 0: | |
if compress: | |
dst,status=backup_compress(fullpath, bfile) | |
if not dst: | |
msg=status | |
status=pynsca.CRITICAL | |
else: | |
msg="Successfully taken backup of %s at location %s" %(db,dst) | |
status=pynsca.OK | |
else: | |
msg="Successfully taken backup of %s at location %s" %(db,fullpath) | |
status=pynsca.OK | |
else: | |
msg='Error: taking backup for database '+ db | |
status=pynsca.CRITICAL | |
if os.path.isfile(fullpath): | |
os.remove(fullpath) | |
print msg | |
if nagios_host: | |
send_nagios(nagios_host,host,service_name+"_"+db,status,msg) | |
#-------------------------------------------------------------------------------------------------------------------------- | |
def backup_compress(path, bfile): | |
try: | |
dest=path+'.tar.gz' | |
tar = tarfile.open(dest, 'w:gz') | |
tar.add(path, arcname=bfile) | |
tar.close() | |
set_permissions(dest) | |
except Exception as e: | |
msg='Error compressing {0} ({1}): {2}'.format(path, e.errno, e.strerror) | |
print msg | |
return None,msg | |
os.remove(path) | |
return dest,"OK" | |
def cleanup_files(path, age): | |
if age is not None: | |
now = time.time() | |
for bf in os.listdir(path): | |
f = os.path.join(path, bf) | |
if os.stat(f).st_mtime < now - age * 86400 and os.path.isfile(f): | |
try: | |
os.remove(f) | |
except IOError as e: | |
print "I/O error({0}): {1}".format(e.errno, e.strerror) | |
def send_nagios(nagios_host,host,service_name,status,msg): | |
notif = NSCANotifier(nagios_host,monitoring_port, encryption_mode, nsca_password) | |
notif.svc_result(host,service_name,status,msg) | |
#print nagios_host,host,service_name,status,msg | |
def main(): | |
args = get_args() | |
db_list=args.dblist | |
mysql_backup(db_list, args.conf, args.backup_directory, args.compress,args.nagios) | |
cleanup_files(args.backup_directory, args.age) | |
if __name__ == "__main__": | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment