From dfdb940b3337940ab341f7dedd22351fa63e0e86 Mon Sep 17 00:00:00 2001 From: Lorenz <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 7 Sep 2022 15:58:17 +0200 Subject: [PATCH 01/15] Convert to python3 and correct some formatting (#21) - Automatically switched python3 - Also removed some whitespaces, sorry about that. Authored-by: rincewind --- check_bareos.py | 132 +++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 69 deletions(-) diff --git a/check_bareos.py b/check_bareos.py index 146c8e2..4a2b01f 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -1,11 +1,11 @@ -#!/usr/bin/python +#!/usr/bin/python3 # ---------------------------------------------------- # # File : check_bareos # Author : Philipp Posovszky, DLR # E-Mail: Philipp.Posovszky@dlr.de # Date : 22/04/2015 -# +# # Modifications : Thomas Widhalm, NETways GmbH # E-Mail: widhalmt@widhalm.or.at # @@ -15,7 +15,7 @@ # it under the terms of the GNU General Public License version 3.0 # # Changelog: -# - 1.0.1 remove 'error' tapes from expire check and correct the help description +# - 1.0.1 remove 'error' tapes from expire check and correct the help description # - 1.0.2 start to rework for chosing correct query for the database type (MySQL -vs - PostgreSQL) # - 1.0.3 add port parameter for MySQL and PostgreSQL databases # @@ -27,7 +27,7 @@ import psycopg2.extras import sys import subprocess -import MySQLdb +import MySQLdb # Variables databaseName = 'bareos' @@ -43,7 +43,7 @@ def createBackupKindString(full, inc, diff): if inc: kind.append("'I'") if diff: - kind.append("'D'") + kind.append("'D'") return ",".join(kind) @@ -96,14 +96,14 @@ def checkFailedBackups(courser, time, warning, critical): checkState["returnCode"] = 0 checkState["returnMessage"] = "OK - Only " + str(result) + " Backups failed in the last " + str(time) + " days" checkState["performanceData"] = "Failed=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" - + return checkState - - + + return checkState - + def checkBackupSize(courser, time, kind, factor): - if time != None: + if time != None: # MySQL needs other Queries than PostgreSQL if(databaseType == "psql"): query = """ @@ -130,7 +130,7 @@ def checkBackupSize(courser, time, kind, factor): courser.execute(query) results = courser.fetchone() # Returns a value return results[0] - + def checkTotalBackupSize(cursor, time, kind, unit, warning, critical): checkState = {} result = checkBackupSize(cursor, time, kind, createFactor(unit)) @@ -154,7 +154,7 @@ def checkTotalBackupSize(cursor, time, kind, unit, warning, critical): checkState["returnMessage"] = "OK - " + str(result) + " " + unit + " Kind:" + kind checkState["performanceData"] = "Size=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState - + def checkOversizedBackups(courser, time, size, kind, unit, warning, critical): checkState = {} if time == None: @@ -176,8 +176,8 @@ def checkOversizedBackups(courser, time, size, kind, unit, warning, critical): """ courser.execute(query) results = courser.fetchall() # Returns a value - result = len(results) - + result = len(results) + if result >= int(critical): checkState["returnCode"] = 2 checkState["returnMessage"] = "CRITICAL - " + str(result) + " " + kind + " Backups larger than " + str(size) + " " + unit + " in the last " + str(time) + " days" @@ -210,8 +210,8 @@ def checkEmptyBackups(cursor, time, kind, warning, critical): """ cursor.execute(query) results = cursor.fetchall() # Returns a value - result = len(results) - + result = len(results) + if result >= int(critical): checkState["returnCode"] = 2 checkState["returnMessage"] = "CRITICAL - " + str(result) + " successful " + str(kind) + " backups are empty" @@ -223,7 +223,7 @@ def checkEmptyBackups(cursor, time, kind, warning, critical): checkState["returnMessage"] = "OK - All " + str(kind) + " backups are fine" checkState["performanceData"] = "EmptyBackups=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState - + # Checks on Jobs def checkJobs(cursor, state, kind, time, warning, critical): @@ -245,7 +245,7 @@ def checkJobs(cursor, state, kind, time, warning, critical): Where Job.JobStatus like '"""+str(state)+"""' and (starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY) or starttime IS NULL) and Job.Level in ("""+kind+"""); """ cursor.execute(query) - results = cursor.fetchone() # Returns a value + results = cursor.fetchone() # Returns a value result = float(results[0]) if result >= int(critical): @@ -280,7 +280,7 @@ def checkSingleJob(cursor, name, state, kind, time, warning, critical): Where Job.Name like '%"""+name+"""%' and Job.JobStatus like '"""+state+"""' and (starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY) or starttime IS NULL) and Job.Level in ("""+kind+"""); """ cursor.execute(query) - results = cursor.fetchall() # Returns a value + results = cursor.fetchall() # Returns a value result = len(results) if result >= int(critical): @@ -315,7 +315,7 @@ def checkRunTimeJobs(cursor,name,state,time,warning,critical): Where starttime < DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY) and Job.JobStatus like '"""+state+"""'; """ cursor.execute(query) - results = cursor.fetchone() # Returns a value + results = cursor.fetchone() # Returns a value result = float(results[0]) if result >= int(critical): @@ -331,7 +331,7 @@ def checkRunTimeJobs(cursor,name,state,time,warning,critical): return checkState - + # Checks on Tapes def checkTapesInStorage(cursor, warning, critical): checkState = {} @@ -344,9 +344,9 @@ def checkTapesInStorage(cursor, warning, critical): AND Media.StorageId=Storage.StorageId; """ cursor.execute(query) - results = cursor.fetchone() # Returns a value + results = cursor.fetchone() # Returns a value result = float(results[0]) - + if result <= int(critical): checkState["returnCode"] = 2 checkState["returnMessage"] = "CRITICAL - Only " + str(result) + " Tapes are in the Storage" @@ -367,9 +367,9 @@ def checkExpiredTapes(cursor, warning, critical): WHERE lastwritten+(media.volretention * '1 second'::INTERVAL)now() and volstatus not like 'Error';; """ cursor.execute(query) - results = cursor.fetchone() # Returns a value + results = cursor.fetchone() # Returns a value result = float(results[0]) - + if result <= int(critical): checkState["returnCode"] = 2 checkState["returnMessage"] = "CRITICAL - Only " + str(result) + " will expire in next " + str(time) + " days" @@ -405,7 +405,7 @@ def checkWillExpiredTapes(cursor, time, warning, critical): checkState["returnCode"] = 0 checkState["returnMessage"] = "OK - Tapes " + str(result) + " will expire in next " + str(time) + " days" checkState["performanceData"] = "Expire=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" - + return checkState def checkReplaceTapes(cursor, mounts, warning, critical): @@ -417,7 +417,7 @@ def checkReplaceTapes(cursor, mounts, warning, critical): (VolStatus='Disabled'); """ cursor.execute(query) - results = cursor.fetchone() # Returns a value + results = cursor.fetchone() # Returns a value result = float(results[0]) if result >= int(critical): @@ -431,10 +431,10 @@ def checkReplaceTapes(cursor, mounts, warning, critical): checkState["returnMessage"] = "OK - Tapes " + str(result) + " have to be replaced in the near future" checkState["performanceData"] = "Replace=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" - return checkState + return checkState + + - - def checkEmptyTapes(courser, warning, critical): checkState = {} @@ -447,7 +447,7 @@ def checkEmptyTapes(courser, warning, critical): AND (VolStatus like 'Purged' or VolStatus like 'Recycle' or lastwritten+(media.volretention * '1 second'::INTERVAL) Date: Wed, 7 Sep 2022 15:59:39 +0200 Subject: [PATCH 02/15] Add better error handling in printNagiosOutput() --- check_bareos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check_bareos.py b/check_bareos.py index 4a2b01f..390b3db 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -497,7 +497,7 @@ def connectDB(userName, pw, hostName, database, port): def printNagiosOutput(checkResult): if checkResult != None: - print((checkResult["returnMessage"] + "|" + checkResult["performanceData"])) + print((checkResult["returnMessage"] + "|" + checkResult.get("performanceData", ";;;;"))) sys.exit(checkResult["returnCode"]) else: print("Critical - Error in Script") From cd746c7a81dad18d19f0fbe6ca479639096445fe Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Wed, 7 Sep 2022 16:00:08 +0200 Subject: [PATCH 03/15] Update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index ba74660..580c0c8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ __pycache__/ # Distribution / packaging .Python env/ +venv/ +.venv/ build/ develop-eggs/ dist/ From 353bd673057ad1ec0016b32940ade3e73cc1d33d Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Wed, 7 Sep 2022 16:02:02 +0200 Subject: [PATCH 04/15] Update README and add requirements.txt --- README.md | 14 ++++++++------ requirements.txt | 2 ++ 2 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 requirements.txt diff --git a/README.md b/README.md index 1abfc09..88e39bd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # check_bareos + Icinga Monitoring Plugin to check Bareos Backup Director databases Main Git Repository: https://github.com/widhalmt/check_bareos @@ -8,17 +9,21 @@ This project is mainly aimed at fixing some bugs. If you want to add features contribute in the git project or sent an email to the author or git repository owner. +## Setup -## Check Examples: +Requires Python 3 to be installed. -Note: use the postgresql database bareos and login without password +Requires the Python `requirements.txt` to be installed. + +## Examples +Note: use the postgresql database bareos and login without password #### Check if a full backup has 0 Bytes(is Empty) and trigger warning it is at least 1 and trigger ciritcal if more than 5 are empty ```check_bareos.py -u bareos -d p status -e -f -w 1 -c 5``` -##### Check if a diff/inc backup is larger than 2 TB (default value) and trigger warning it is at least 1 and trigger ciritcal if more than 5 are empty +##### Check if a diff/inc backup is larger than 2 TB (default value) and trigger warning it is at least 1 and trigger ciritcal if more than 5 are empty ```check_bareos.py -u bareos -d p status -o -d -i -w 1 -c 5``` @@ -56,6 +61,3 @@ Note: use the postgresql database bareos and login without password #### Check how much tapes will expire in the next 14 days ```check_bareos.py -u bareos -d p tape -wex -t 14 -w 10 -c 5``` - - - diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ea412ef --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +mysqlclient==2.1.1 +psycopg2-binary==2.9.3 From 1d3926277b4653e704ee5ca84a0cb21777bbece5 Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Wed, 7 Sep 2022 16:05:13 +0200 Subject: [PATCH 05/15] Change Version to be variable and fix its output --- check_bareos.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/check_bareos.py b/check_bareos.py index 390b3db..1e8530d 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -9,8 +9,6 @@ # Modifications : Thomas Widhalm, NETways GmbH # E-Mail: widhalmt@widhalm.or.at # -# Version: 1.0.3 -# # This program is free software; you can redistribute it or modify # it under the terms of the GNU General Public License version 3.0 # @@ -29,11 +27,16 @@ import subprocess import MySQLdb + +# Constants +VERSION = '1.0.3' + # Variables databaseName = 'bareos' # Used to differentiate between database specific queries databaseType = 'mysql' + def createBackupKindString(full, inc, diff): if full == False and inc == False and diff == False: return "'F','D','I'" @@ -510,7 +513,7 @@ def argumentParser(): group.add_argument('-p', '--password', dest='password', action='store', help='password for the database connections', default="") group.add_argument('-H', '--Host', dest='host', action='store', help='database host', default="127.0.0.1") group.add_argument('-P', '--port', dest='port', action='store', help='database port', default=3306, type=int) - group.add_argument('-v', '--version', action='version', version='%(prog)s 1.0.0') + group.add_argument('-v', '--version', action='version', version=f'%(prog)s {VERSION}') parser.add_argument('-d', '--database', dest='database', choices=['mysql', 'm', 'postgresql', 'p', 'psql'], default='mysql', help='the database kind for the database connection (m=mysql, p=psql) (Default=Mysql)') subParser = parser.add_subparsers() From f5bfe015b76d30af98cc0d58d85a5c45890b5a46 Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Thu, 8 Sep 2022 14:38:04 +0200 Subject: [PATCH 06/15] Change "unable to connect" from Critical to Unknown - Fixes https://github.com/NETWAYS/check_bareos/issues/16 --- check_bareos.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/check_bareos.py b/check_bareos.py index 1e8530d..303da50 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -483,8 +483,8 @@ def connectDB(userName, pw, hostName, database, port): return cursor except psycopg2.DatabaseError as e: checkState = {} - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(e)[:-1] + checkState["returnCode"] = 3 + checkState["returnMessage"] = "UNKNOWN - " + str(e)[:-1] checkState["performanceData"] = ";;;;" printNagiosOutput(checkState) @@ -493,8 +493,8 @@ def connectDB(userName, pw, hostName, database, port): conn = MySQLdb.connect(host=hostName, user=userName, passwd=pw, db=databaseName, port=port) except MySQLdb.Error as e: checkState = {} - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(e)[:-1] + checkState["returnCode"] = 3 + checkState["returnMessage"] = "UNKNOWN - " + str(e)[:-1] checkState["performanceData"] = ";;;;" printNagiosOutput(checkState) @@ -503,8 +503,8 @@ def printNagiosOutput(checkResult): print((checkResult["returnMessage"] + "|" + checkResult.get("performanceData", ";;;;"))) sys.exit(checkResult["returnCode"]) else: - print("Critical - Error in Script") - sys.exit(2) + print("UNKNOWN - Error in Script") + sys.exit(3) def argumentParser(): parser = argparse.ArgumentParser(description='Check status of the bareos backups') From cc063da7ff645150c13b2e9942a471e731267d9a Mon Sep 17 00:00:00 2001 From: Adrien Robert Date: Tue, 8 Nov 2022 08:42:44 +0100 Subject: [PATCH 07/15] Add possibility to install only required dependencies --- check_bareos.py | 9 ++++----- requirements-mysql.txt | 1 + requirements.txt => requirements-postgres.txt | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 requirements-mysql.txt rename requirements.txt => requirements-postgres.txt (54%) diff --git a/check_bareos.py b/check_bareos.py index 303da50..8c1bce7 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -17,15 +17,11 @@ # - 1.0.2 start to rework for chosing correct query for the database type (MySQL -vs - PostgreSQL) # - 1.0.3 add port parameter for MySQL and PostgreSQL databases # -# # Plugin check for icinga # ---------------------------------------------------- # import argparse -import psycopg2 -import psycopg2.extras import sys import subprocess -import MySQLdb # Constants @@ -473,6 +469,8 @@ def connectDB(userName, pw, hostName, database, port): global databaseType databaseType = 'psql' try: + import psycopg2 + import psycopg2.extras # Define our connection string connString = "host='" + hostName + "' port=" + str(port) + " dbname='" + databaseName + "' user='" + userName + "' password='" + pw + "'" # get a connection, if a connect cannot be made an exception will be raised here @@ -490,7 +488,8 @@ def connectDB(userName, pw, hostName, database, port): if(database == "mysql" or database == "m"): try: - conn = MySQLdb.connect(host=hostName, user=userName, passwd=pw, db=databaseName, port=port) + import MySQLdb + conn = MySQLdb.connect(host=hostName, user=userName, password=pw, database=databaseName, port=port) except MySQLdb.Error as e: checkState = {} checkState["returnCode"] = 3 diff --git a/requirements-mysql.txt b/requirements-mysql.txt new file mode 100644 index 0000000..485d75f --- /dev/null +++ b/requirements-mysql.txt @@ -0,0 +1 @@ +mysqlclient==2.1.1 diff --git a/requirements.txt b/requirements-postgres.txt similarity index 54% rename from requirements.txt rename to requirements-postgres.txt index ea412ef..4881093 100644 --- a/requirements.txt +++ b/requirements-postgres.txt @@ -1,2 +1 @@ -mysqlclient==2.1.1 psycopg2-binary==2.9.3 From 497ce206a7d6f221c1651e24409cf35452d3e872 Mon Sep 17 00:00:00 2001 From: Adrien Robert Date: Tue, 8 Nov 2022 08:49:37 +0100 Subject: [PATCH 08/15] Fix: MySQL connection was't returning a cursor So the requesting of the DB was impossible Maybe it fixes : NETWAYS/check_bareos#8 --- check_bareos.py | 1 + 1 file changed, 1 insertion(+) diff --git a/check_bareos.py b/check_bareos.py index 8c1bce7..dd6daed 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -490,6 +490,7 @@ def connectDB(userName, pw, hostName, database, port): try: import MySQLdb conn = MySQLdb.connect(host=hostName, user=userName, password=pw, database=databaseName, port=port) + return conn.cursor() except MySQLdb.Error as e: checkState = {} checkState["returnCode"] = 3 From 68e2879df655eea92b55cfc9386e8b1949a67dca Mon Sep 17 00:00:00 2001 From: Adrien Robert Date: Tue, 8 Nov 2022 08:32:42 +0100 Subject: [PATCH 09/15] Bump version to 1.1.0 --- check_bareos.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/check_bareos.py b/check_bareos.py index dd6daed..0ecad8a 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -16,6 +16,9 @@ # - 1.0.1 remove 'error' tapes from expire check and correct the help description # - 1.0.2 start to rework for chosing correct query for the database type (MySQL -vs - PostgreSQL) # - 1.0.3 add port parameter for MySQL and PostgreSQL databases +# - 1.1.0 add python3 compatibility +# split import to be able to not install unnecessary dependencies +# Fixes issues with mysql connection # # Plugin check for icinga # ---------------------------------------------------- # @@ -25,7 +28,7 @@ # Constants -VERSION = '1.0.3' +VERSION = '1.1.0' # Variables databaseName = 'bareos' From e56ec29440594afda557d1ec9467211738410ce7 Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Tue, 8 Nov 2022 17:19:47 +0100 Subject: [PATCH 10/15] Update README --- README.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 88e39bd..36ca295 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,21 @@ Icinga Monitoring Plugin to check Bareos Backup Director databases -Main Git Repository: https://github.com/widhalmt/check_bareos -At the moment this is a fork repository to make it to a synchronized project with thise site. - -This project is mainly aimed at fixing some bugs. - -If you want to add features contribute in the git project or sent an email to the author or git repository owner. - ## Setup Requires Python 3 to be installed. -Requires the Python `requirements.txt` to be installed. +Depending on your database setup either `requirements-mysql.txt` or `requirements-postgres.txt` needs to be installed. -## Examples +# Examples Note: use the postgresql database bareos and login without password -#### Check if a full backup has 0 Bytes(is Empty) and trigger warning it is at least 1 and trigger ciritcal if more than 5 are empty +#### Check if a full backup has 0 Bytes(is Empty) and trigger warning it is at least 1 and trigger ciritcal if more than 5 are empty ```check_bareos.py -u bareos -d p status -e -f -w 1 -c 5``` -##### Check if a diff/inc backup is larger than 2 TB (default value) and trigger warning it is at least 1 and trigger ciritcal if more than 5 are empty +#### Check if a diff/inc backup is larger than 2 TB (default value) and trigger warning it is at least 1 and trigger ciritcal if more than 5 are empty ```check_bareos.py -u bareos -d p status -o -d -i -w 1 -c 5``` From ec05d5cebd447f9c2cbf99877022abfe2177efd4 Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Wed, 16 Nov 2022 09:49:49 +0100 Subject: [PATCH 11/15] Remove some unnecessary formating --- check_bareos.py | 50 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/check_bareos.py b/check_bareos.py index 0ecad8a..863c0fc 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -24,7 +24,6 @@ # ---------------------------------------------------- # import argparse import sys -import subprocess # Constants @@ -71,7 +70,7 @@ def checkFailedBackups(courser, time, warning, critical): if time == None: time = 7 # MySQL needs other Queries than PostgreSQL - if(databaseType == "psql"): + if databaseType == "psql": query = """ SELECT Job.Name,Level,starttime, JobStatus FROM Job @@ -101,13 +100,10 @@ def checkFailedBackups(courser, time, warning, critical): return checkState - - return checkState - def checkBackupSize(courser, time, kind, factor): if time != None: # MySQL needs other Queries than PostgreSQL - if(databaseType == "psql"): + if databaseType == "psql": query = """ SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) FROM Job @@ -163,7 +159,7 @@ def checkOversizedBackups(courser, time, size, kind, unit, warning, critical): time = 7 factor = createFactor(unit) # MySQL needs other Queries than PostgreSQL - if(databaseType == "psql"): + if databaseType == "psql": query = """ SELECT Job.Name,Level,starttime, JobBytes/""" + str(float(factor)) + """ FROM Job @@ -197,7 +193,7 @@ def checkEmptyBackups(cursor, time, kind, warning, critical): if time == None: time = 7 # MySQL needs other Queries than PostgreSQL - if(databaseType == "psql"): + if databaseType == "psql": query = """ SELECT Job.Name,Level,starttime FROM Job @@ -233,7 +229,7 @@ def checkJobs(cursor, state, kind, time, warning, critical): if time == None: time = 7 # MySQL needs other Queries than PostgreSQL - if(databaseType == "psql"): + if databaseType == "psql": query = """ Select count(Job.Name) From Job @@ -268,7 +264,7 @@ def checkSingleJob(cursor, name, state, kind, time, warning, critical): if time == None: time = 7 # MySQL needs other Queries than PostgreSQL - if(databaseType == "psql"): + if databaseType == "psql": query = """ Select Job.Name,Job.JobStatus, Job.Starttime FROm Job @@ -303,7 +299,7 @@ def checkRunTimeJobs(cursor,name,state,time,warning,critical): if time == None: time = 7 # MySQL needs other Queries than PostgreSQL - if(databaseType == "psql"): + if databaseType == "psql": query = """ Select Count(Job.Name) FROm Job @@ -511,7 +507,7 @@ def printNagiosOutput(checkResult): def argumentParser(): parser = argparse.ArgumentParser(description='Check status of the bareos backups') - group = parser.add_argument_group(); + group = parser.add_argument_group() group.add_argument('-u', '--user', dest='user', action='store', required=True, help='user name for the database connections') group.add_argument('-p', '--password', dest='password', action='store', help='password for the database connections', default="") group.add_argument('-H', '--Host', dest='host', action='store', help='database host', default="127.0.0.1") @@ -521,7 +517,7 @@ def argumentParser(): subParser = parser.add_subparsers() - jobParser = subParser.add_parser('job', help='Specific checks on a job'); + jobParser = subParser.add_parser('job', help='Specific checks on a job') jobGroup = jobParser.add_mutually_exclusive_group(required=True) jobParser.set_defaults(func=checkJob) jobGroup.add_argument('-js', '--checkJobs', dest='checkJobs', action='store_true', help='Check how many jobs are in a specific state [default=queued]') @@ -537,8 +533,8 @@ def argumentParser(): jobParser.add_argument('-i', '--inc', dest='inc', action='store_true', help='Backup kind inc') jobParser.add_argument('-d', '--diff', dest='diff', action='store_true', help='Backup kind diff') - tapeParser = subParser.add_parser('tape', help='Specific checks on a tapes'); - tapeGroup = tapeParser.add_mutually_exclusive_group(required=True); + tapeParser = subParser.add_parser('tape', help='Specific checks on a tapes') + tapeGroup = tapeParser.add_mutually_exclusive_group(required=True) tapeParser.set_defaults(func=checkTape) tapeGroup.add_argument('-e', '--emptyTapes', dest='emptyTapes', action='store_true', help='Count empty tapes in the storage (Status Purged/Expired)') tapeGroup.add_argument('-ts', '--tapesInStorage', dest='tapesInStorage', action='store_true', help='Count how much tapes are in the storage') @@ -551,8 +547,8 @@ def argumentParser(): tapeParser.add_argument('-t', '--time', dest='time', action='store', help='Time in days (default=7 days)', default=7) - statusParser = subParser.add_parser('status', help='Specific status informations'); - statusGroup = statusParser.add_mutually_exclusive_group(required=True); + statusParser = subParser.add_parser('status', help='Specific status informations') + statusGroup = statusParser.add_mutually_exclusive_group(required=True) statusParser.set_defaults(func=checkStatus) statusGroup.add_argument('-b', '--totalBackupsSize', dest='totalBackupsSize', action='store_true', help='the size of all backups in the database [use time and kind for mor restrictions]') statusGroup.add_argument('-e', '--emptyBackups', dest='emptyBackups', action='store_true', help='Check if a successful backup have 0 bytes [only wise for full backups]') @@ -581,7 +577,7 @@ def checkConnection(cursor): return True def checkTape(args): - cursor = connectDB(args.user, args.password, args.host, args.database, args.port); + cursor = connectDB(args.user, args.password, args.host, args.database, args.port) checkResult = {} if checkConnection(cursor): if args.emptyTapes: @@ -594,12 +590,12 @@ def checkTape(args): checkResult = checkExpiredTapes(cursor, args.warning, args.critical) elif args.willExpire: checkResult = checkWillExpiredTapes(cursor, args.time, args.warning, args.critical) - printNagiosOutput(checkResult); - cursor.close(); + printNagiosOutput(checkResult) + cursor.close() def checkJob(args): - cursor = connectDB(args.user, args.password, args.host, args.database, args.port); + cursor = connectDB(args.user, args.password, args.host, args.database, args.port) checkResult = {} if checkConnection(cursor): if args.checkJob: @@ -609,13 +605,13 @@ def checkJob(args): kind = createBackupKindString(args.full, args.inc, args.diff) checkResult = checkJobs(cursor, args.state, kind, args.time, args.warning, args.critical) elif args.runTimeJobs: - checkResult = checkRunTimeJobs(cursor, args.name,args.state, args.time, args.warning, args.critical) - printNagiosOutput(checkResult); - cursor.close(); + checkResult = checkRunTimeJobs(cursor, args.name, args.state, args.time, args.warning, args.critical) + printNagiosOutput(checkResult) + cursor.close() def checkStatus(args): - cursor = connectDB(args.user, args.password, args.host, args.database, args.port); + cursor = connectDB(args.user, args.password, args.host, args.database, args.port) checkResult = {} if checkConnection(cursor): if args.emptyBackups: @@ -630,8 +626,8 @@ def checkStatus(args): elif args.failedBackups: kind = createBackupKindString(args.full, args.inc, args.diff) checkResult = checkFailedBackups(cursor, args.time, args.warning, args.critical) - printNagiosOutput(checkResult); - cursor.close(); + printNagiosOutput(checkResult) + cursor.close() if __name__ == '__main__': From 329ca9a4d003a7548f8f04834d154e8898b805f1 Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Wed, 16 Nov 2022 09:55:28 +0100 Subject: [PATCH 12/15] Add pylint --- .pylintrc | 18 ++++++++++++++++++ Makefile | 6 ++++++ 2 files changed, 24 insertions(+) create mode 100644 .pylintrc create mode 100644 Makefile diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..f02d7e1 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,18 @@ +# pylint config +[FORMAT] +good-names=m,p,ok +[MESSAGES CONTROL] +disable=fixme, + line-too-long, + too-many-locals, + too-many-arguments, + invalid-name, + redefined-outer-name, + bad-indentation, + too-many-statements, + too-many-branches, + import-outside-toplevel, + missing-function-docstring, + missing-module-docstring, + missing-class-docstring, + consider-using-f-string diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..720ef9a --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +.PHONY: lint test + +lint: + python -m pylint check_bareos +test: + python -m unittest -v -b From fedd45fa5b544bb8d6ae72b29e5abcdb19ba620f Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Wed, 16 Nov 2022 12:31:31 +0100 Subject: [PATCH 13/15] Fix singleton-comparison --- check_bareos.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/check_bareos.py b/check_bareos.py index 863c0fc..534acd0 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -36,7 +36,7 @@ def createBackupKindString(full, inc, diff): - if full == False and inc == False and diff == False: + if full is False and inc is False and diff is False: return "'F','D','I'" kind = [] if full: @@ -67,7 +67,7 @@ def getState(state): def checkFailedBackups(courser, time, warning, critical): checkState = {} - if time == None: + if time is None: time = 7 # MySQL needs other Queries than PostgreSQL if databaseType == "psql": @@ -101,7 +101,7 @@ def checkFailedBackups(courser, time, warning, critical): return checkState def checkBackupSize(courser, time, kind, factor): - if time != None: + if time is not None: # MySQL needs other Queries than PostgreSQL if databaseType == "psql": query = """ @@ -155,7 +155,7 @@ def checkTotalBackupSize(cursor, time, kind, unit, warning, critical): def checkOversizedBackups(courser, time, size, kind, unit, warning, critical): checkState = {} - if time == None: + if time is None: time = 7 factor = createFactor(unit) # MySQL needs other Queries than PostgreSQL @@ -190,7 +190,7 @@ def checkOversizedBackups(courser, time, size, kind, unit, warning, critical): def checkEmptyBackups(cursor, time, kind, warning, critical): checkState = {} - if time == None: + if time is None: time = 7 # MySQL needs other Queries than PostgreSQL if databaseType == "psql": @@ -226,7 +226,7 @@ def checkEmptyBackups(cursor, time, kind, warning, critical): # Checks on Jobs def checkJobs(cursor, state, kind, time, warning, critical): checkState = {} - if time == None: + if time is None: time = 7 # MySQL needs other Queries than PostgreSQL if databaseType == "psql": @@ -261,7 +261,7 @@ def checkJobs(cursor, state, kind, time, warning, critical): def checkSingleJob(cursor, name, state, kind, time, warning, critical): checkState = {} - if time == None: + if time is None: time = 7 # MySQL needs other Queries than PostgreSQL if databaseType == "psql": @@ -296,7 +296,7 @@ def checkSingleJob(cursor, name, state, kind, time, warning, critical): def checkRunTimeJobs(cursor,name,state,time,warning,critical): checkState = {} - if time == None: + if time is None: time = 7 # MySQL needs other Queries than PostgreSQL if databaseType == "psql": @@ -498,7 +498,7 @@ def connectDB(userName, pw, hostName, database, port): printNagiosOutput(checkState) def printNagiosOutput(checkResult): - if checkResult != None: + if checkResult is not None: print((checkResult["returnMessage"] + "|" + checkResult.get("performanceData", ";;;;"))) sys.exit(checkResult["returnCode"]) else: @@ -568,7 +568,7 @@ def argumentParser(): def checkConnection(cursor): checkResult = {} - if cursor == None: + if cursor is None: checkResult["returnCode"] = 2 checkResult["returnMessage"] = "CRITICAL - No DB connection" printNagiosOutput(checkResult) From 5649a3f41a4db77759d2bafd6ae60818970e6dc6 Mon Sep 17 00:00:00 2001 From: Markus Opolka Date: Wed, 16 Nov 2022 12:36:41 +0100 Subject: [PATCH 14/15] Fix bad-indentation --- .pylintrc | 1 - check_bareos.py | 384 +++++++++++++++++++++++++----------------------- 2 files changed, 199 insertions(+), 186 deletions(-) diff --git a/.pylintrc b/.pylintrc index f02d7e1..a720411 100644 --- a/.pylintrc +++ b/.pylintrc @@ -8,7 +8,6 @@ disable=fixme, too-many-arguments, invalid-name, redefined-outer-name, - bad-indentation, too-many-statements, too-many-branches, import-outside-toplevel, diff --git a/check_bareos.py b/check_bareos.py index 534acd0..694b28e 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -88,139 +88,146 @@ def checkFailedBackups(courser, time, warning, critical): result = len(results) if result >= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(result) + " Backups failed/canceled last " + str(time) + " days" + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - " + str(result) + " Backups failed/canceled last " + str(time) + " days" elif result >= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - " + str(result) + " Backups failed/canceled last " + str(time) + " days" + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - " + str(result) + " Backups failed/canceled last " + str(time) + " days" else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - Only " + str(result) + " Backups failed in the last " + str(time) + " days" + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - Only " + str(result) + " Backups failed in the last " + str(time) + " days" + checkState["performanceData"] = "Failed=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState def checkBackupSize(courser, time, kind, factor): - if time is not None: - # MySQL needs other Queries than PostgreSQL - if databaseType == "psql": - query = """ - SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) - FROM Job - Where Level in (""" + kind + """) and starttime > (now()-""" + str(time) + """ * '1 day'::INTERVAL) ; - """ - # According to --help output MySQL is the default - else: - query = """ - SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) - FROM Job - Where Level in (""" + kind + """) and starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY); - """ - courser.execute(query) - results = courser.fetchone() # Returns a value - return results[0] - else: - query = """ - SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) - FROM Job - Where Level in (""" + kind + """); - """ - courser.execute(query) - results = courser.fetchone() # Returns a value - return results[0] + if time is not None: + # MySQL needs other Queries than PostgreSQL + if databaseType == "psql": + query = """ + SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) + FROM Job + Where Level in (""" + kind + """) and starttime > (now()-""" + str(time) + """ * '1 day'::INTERVAL) ; + """ + # According to --help output MySQL is the default + else: + query = """ + SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) + FROM Job + Where Level in (""" + kind + """) and starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY); + """ + courser.execute(query) + results = courser.fetchone() # Returns a value + return results[0] + else: + query = """ + SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) + FROM Job + Where Level in (""" + kind + """); + """ + courser.execute(query) + results = courser.fetchone() # Returns a value + return results[0] def checkTotalBackupSize(cursor, time, kind, unit, warning, critical): - checkState = {} - result = checkBackupSize(cursor, time, kind, createFactor(unit)) - if result >= int(critical): - checkState["returnCode"] = 2 - if args.time: - checkState["returnMessage"] = "CRITICAL - " + str(result) + " " + unit + " Kind:" + kind + " Days: " + str(time) - else: - checkState["returnMessage"] = "CRITICAL - " + str(result) + " " + unit + " Kind:" + kind - elif result >= int(warning): - checkState["returnCode"] = 1 - if args.time: - checkState["returnMessage"] = "WARNING - " + str(result) + " " + unit + " Kind:" + kind + " Days: " + str(time) - else: - checkState["returnMessage"] = "WARNING - " + str(result) + " " + unit + " Kind:" + kind - else: - checkState["returnCode"] = 0 - if args.time: - checkState["returnMessage"] = "OK - " + str(result) + " " + unit + " Kind:" + kind + " Days: " + str(time) - else: - checkState["returnMessage"] = "OK - " + str(result) + " " + unit + " Kind:" + kind - checkState["performanceData"] = "Size=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" - return checkState + checkState = {} + result = checkBackupSize(cursor, time, kind, createFactor(unit)) + if result >= int(critical): + checkState["returnCode"] = 2 + if args.time: + checkState["returnMessage"] = "CRITICAL - " + str(result) + " " + unit + " Kind:" + kind + " Days: " + str(time) + else: + checkState["returnMessage"] = "CRITICAL - " + str(result) + " " + unit + " Kind:" + kind + elif result >= int(warning): + checkState["returnCode"] = 1 + if args.time: + checkState["returnMessage"] = "WARNING - " + str(result) + " " + unit + " Kind:" + kind + " Days: " + str(time) + else: + checkState["returnMessage"] = "WARNING - " + str(result) + " " + unit + " Kind:" + kind + else: + checkState["returnCode"] = 0 + if args.time: + checkState["returnMessage"] = "OK - " + str(result) + " " + unit + " Kind:" + kind + " Days: " + str(time) + else: + checkState["returnMessage"] = "OK - " + str(result) + " " + unit + " Kind:" + kind + + checkState["performanceData"] = "Size=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" + + return checkState def checkOversizedBackups(courser, time, size, kind, unit, warning, critical): - checkState = {} - if time is None: - time = 7 - factor = createFactor(unit) - # MySQL needs other Queries than PostgreSQL - if databaseType == "psql": - query = """ - SELECT Job.Name,Level,starttime, JobBytes/""" + str(float(factor)) + """ - FROM Job - Where Level in (""" + kind + """) and starttime > (now()::date-""" + str(time) + """ * '1 day'::INTERVAL) and JobBytes/""" + str(float(factor)) + """>""" + str(size) + """; - """ - # MySQL is the default - else: - query = """ - SELECT Job.Name,Level,starttime, JobBytes/""" + str(float(factor)) + """ - FROM Job - Where Level in (""" + kind + """) and starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY) and JobBytes/""" + str(float(factor)) + """>""" + str(size) + """; - """ - courser.execute(query) - results = courser.fetchall() # Returns a value - result = len(results) - - if result >= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(result) + " " + kind + " Backups larger than " + str(size) + " " + unit + " in the last " + str(time) + " days" - elif result >= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - " + str(result) + " " + kind + " Backups larger than " + str(size) + " " + unit + " in the last " + str(time) + " days" - else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - No " + kind + " Backup larger than " + str(size) + " " + unit + " in the last " + str(time) + " days" - checkState["performanceData"] = "OverSized=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" - return checkState + checkState = {} + if time is None: + time = 7 + factor = createFactor(unit) + # MySQL needs other Queries than PostgreSQL + if databaseType == "psql": + query = """ + SELECT Job.Name,Level,starttime, JobBytes/""" + str(float(factor)) + """ + FROM Job + Where Level in (""" + kind + """) and starttime > (now()::date-""" + str(time) + """ * '1 day'::INTERVAL) and JobBytes/""" + str(float(factor)) + """>""" + str(size) + """; + """ + # MySQL is the default + else: + query = """ + SELECT Job.Name,Level,starttime, JobBytes/""" + str(float(factor)) + """ + FROM Job + Where Level in (""" + kind + """) and starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY) and JobBytes/""" + str(float(factor)) + """>""" + str(size) + """; + """ + courser.execute(query) + results = courser.fetchall() # Returns a value + result = len(results) + + if result >= int(critical): + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - " + str(result) + " " + kind + " Backups larger than " + str(size) + " " + unit + " in the last " + str(time) + " days" + elif result >= int(warning): + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - " + str(result) + " " + kind + " Backups larger than " + str(size) + " " + unit + " in the last " + str(time) + " days" + else: + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - No " + kind + " Backup larger than " + str(size) + " " + unit + " in the last " + str(time) + " days" + + checkState["performanceData"] = "OverSized=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" + + return checkState def checkEmptyBackups(cursor, time, kind, warning, critical): - checkState = {} - if time is None: - time = 7 - # MySQL needs other Queries than PostgreSQL - if databaseType == "psql": - query = """ - SELECT Job.Name,Level,starttime - FROM Job - Where Level in (""" + str(kind) + """) and JobBytes=0 and starttime > (now()::date-""" + str(time) + """ * '1 day'::INTERVAL) and JobStatus in ('T'); - """ - # MySQL is the default - else: - query = """ - SELECT Job.Name,Level,starttime - FROM Job - Where Level in (""" + str(kind) + """) and JobBytes=0 and starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY) and JobStatus in ('T'); - """ - cursor.execute(query) - results = cursor.fetchall() # Returns a value - result = len(results) - - if result >= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(result) + " successful " + str(kind) + " backups are empty" - elif result >= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - " + str(result) + " successful " + str(kind) + " backups are empty!" - else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - All " + str(kind) + " backups are fine" - checkState["performanceData"] = "EmptyBackups=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" - return checkState + checkState = {} + if time is None: + time = 7 + # MySQL needs other Queries than PostgreSQL + if databaseType == "psql": + query = """ + SELECT Job.Name,Level,starttime + FROM Job + Where Level in (""" + str(kind) + """) and JobBytes=0 and starttime > (now()::date-""" + str(time) + """ * '1 day'::INTERVAL) and JobStatus in ('T'); + """ + # MySQL is the default + else: + query = """ + SELECT Job.Name,Level,starttime + FROM Job + Where Level in (""" + str(kind) + """) and JobBytes=0 and starttime > DATE_SUB(now(), INTERVAL """ + str(time) + """ DAY) and JobStatus in ('T'); + """ + cursor.execute(query) + results = cursor.fetchall() # Returns a value + result = len(results) + + if result >= int(critical): + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - " + str(result) + " successful " + str(kind) + " backups are empty" + elif result >= int(warning): + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - " + str(result) + " successful " + str(kind) + " backups are empty!" + else: + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - All " + str(kind) + " backups are fine" + + checkState["performanceData"] = "EmptyBackups=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" + + return checkState # Checks on Jobs @@ -247,14 +254,15 @@ def checkJobs(cursor, state, kind, time, warning, critical): result = float(results[0]) if result >= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - " + str(result) + " Jobs are in the state: "+str(getState(state)) elif result >= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - " + str(result) + " Jobs are in the state: "+str(getState(state)) else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["performanceData"] = str(getState(state))+"=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState @@ -282,14 +290,15 @@ def checkSingleJob(cursor, name, state, kind, time, warning, critical): result = len(results) if result >= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - " + str(result) + " Jobs are in the state: "+str(getState(state)) elif result >= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - " + str(result) + " Jobs are in the state: "+str(getState(state)) else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - " + str(result) + " Jobs are in the state: "+str(getState(state)) + checkState["performanceData"] = str(getState(state))+"=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState @@ -317,14 +326,15 @@ def checkRunTimeJobs(cursor,name,state,time,warning,critical): result = float(results[0]) if result >= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(result) + " Jobs are running longer than "+str(time)+" days" + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - " + str(result) + " Jobs are running longer than "+str(time)+" days" elif result >= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - " + str(result) + " Jobs are running longer than "+str(time)+" days" + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - " + str(result) + " Jobs are running longer than "+str(time)+" days" else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - " + str(result) + " Jobs are running longer than "+str(time)+" days" + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - " + str(result) + " Jobs are running longer than "+str(time)+" days" + checkState["performanceData"] = "Count=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState @@ -369,14 +379,15 @@ def checkExpiredTapes(cursor, warning, critical): result = float(results[0]) if result <= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - Only " + str(result) + " expired" + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - Only " + str(result) + " expired" elif result <= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - Only " + str(result) + " expired" + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - Only " + str(result) + " expired" else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - Tapes " + str(result) + " expired" + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - Tapes " + str(result) + " expired" + checkState["performanceData"] = "Expired=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState @@ -394,14 +405,15 @@ def checkWillExpiredTapes(cursor, time, warning, critical): result = float(results[0]) if result <= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - Only " + str(result) + " will expire in next " + str(time) + " days" + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - Only " + str(result) + " will expire in next " + str(time) + " days" elif result <= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - Only " + str(result) + " will expire in next " + str(time) + " days" + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - Only " + str(result) + " will expire in next " + str(time) + " days" else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - Tapes " + str(result) + " will expire in next " + str(time) + " days" + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - Tapes " + str(result) + " will expire in next " + str(time) + " days" + checkState["performanceData"] = "Expire=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState @@ -419,14 +431,15 @@ def checkReplaceTapes(cursor, mounts, warning, critical): result = float(results[0]) if result >= int(critical): - checkState["returnCode"] = 2 - checkState["returnMessage"] = "CRITICAL - " + str(result) + " Tapes have to be replaced in the near future" + checkState["returnCode"] = 2 + checkState["returnMessage"] = "CRITICAL - " + str(result) + " Tapes have to be replaced in the near future" elif result >= int(warning): - checkState["returnCode"] = 1 - checkState["returnMessage"] = "WARNING - Only " + str(result) + " Tapes have to be replaced in the near future" + checkState["returnCode"] = 1 + checkState["returnMessage"] = "WARNING - Only " + str(result) + " Tapes have to be replaced in the near future" else: - checkState["returnCode"] = 0 - checkState["returnMessage"] = "OK - Tapes " + str(result) + " have to be replaced in the near future" + checkState["returnCode"] = 0 + checkState["returnMessage"] = "OK - Tapes " + str(result) + " have to be replaced in the near future" + checkState["performanceData"] = "Replace=" + str(result) + ";" + str(warning) + ";" + str(critical) + ";;" return checkState @@ -435,31 +448,32 @@ def checkReplaceTapes(cursor, mounts, warning, critical): def checkEmptyTapes(courser, warning, critical): - checkState = {} - query = """ - SELECT Count(MediaId) - FROM Media,Pool,Storage - WHERE Media.PoolId=Pool.PoolId - AND Slot>0 AND InChanger=1 - AND Media.StorageId=Storage.StorageId - AND (VolStatus like 'Purged' or VolStatus like 'Recycle' or lastwritten+(media.volretention * '1 second'::INTERVAL)0 AND InChanger=1 + AND Media.StorageId=Storage.StorageId + AND (VolStatus like 'Purged' or VolStatus like 'Recycle' or lastwritten+(media.volretention * '1 second'::INTERVAL) Date: Wed, 16 Nov 2022 12:49:44 +0100 Subject: [PATCH 15/15] Minor code fixes - Fixed no-else-return - Simplified conditional statements --- .pylintrc | 19 ++++++++++--------- check_bareos.py | 34 +++++++++++++++++----------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.pylintrc b/.pylintrc index a720411..ea1844b 100644 --- a/.pylintrc +++ b/.pylintrc @@ -3,15 +3,16 @@ good-names=m,p,ok [MESSAGES CONTROL] disable=fixme, - line-too-long, - too-many-locals, - too-many-arguments, - invalid-name, - redefined-outer-name, - too-many-statements, - too-many-branches, + consider-using-f-string, import-outside-toplevel, + inconsistent-return-statements, + invalid-name, + line-too-long, + missing-class-docstring, missing-function-docstring, missing-module-docstring, - missing-class-docstring, - consider-using-f-string + redefined-outer-name, + too-many-arguments, + too-many-branches, + too-many-locals, + too-many-statements diff --git a/check_bareos.py b/check_bareos.py index 694b28e..7291c29 100755 --- a/check_bareos.py +++ b/check_bareos.py @@ -120,15 +120,16 @@ def checkBackupSize(courser, time, kind, factor): courser.execute(query) results = courser.fetchone() # Returns a value return results[0] - else: - query = """ - SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) - FROM Job - Where Level in (""" + kind + """); - """ - courser.execute(query) - results = courser.fetchone() # Returns a value - return results[0] + + query = """ + SELECT ROUND(SUM(JobBytes/""" + str(float(factor)) + """),3) + FROM Job + Where Level in (""" + kind + """); + """ + courser.execute(query) + results = courser.fetchone() # Returns a value + + return results[0] def checkTotalBackupSize(cursor, time, kind, unit, warning, critical): checkState = {} @@ -303,7 +304,7 @@ def checkSingleJob(cursor, name, state, kind, time, warning, critical): return checkState -def checkRunTimeJobs(cursor,name,state,time,warning,critical): +def checkRunTimeJobs(cursor,state,time,warning,critical): checkState = {} if time is None: time = 7 @@ -476,10 +477,9 @@ def checkEmptyTapes(courser, warning, critical): return checkState - def connectDB(userName, pw, hostName, database, port): - if(database == "postgresql" or database == "p" or database == "psql"): - global databaseType + if database in ["postgresql", "p", "psql"]: + global databaseType # pylint: disable=global-statement databaseType = 'psql' try: import psycopg2 @@ -499,7 +499,7 @@ def connectDB(userName, pw, hostName, database, port): checkState["performanceData"] = ";;;;" printNagiosOutput(checkState) - if(database == "mysql" or database == "m"): + if database in ["mysql", "m"]: try: import MySQLdb conn = MySQLdb.connect(host=hostName, user=userName, password=pw, database=databaseName, port=port) @@ -587,8 +587,8 @@ def checkConnection(cursor): checkResult["returnMessage"] = "CRITICAL - No DB connection" printNagiosOutput(checkResult) return False - else: - return True + + return True def checkTape(args): cursor = connectDB(args.user, args.password, args.host, args.database, args.port) @@ -619,7 +619,7 @@ def checkJob(args): kind = createBackupKindString(args.full, args.inc, args.diff) checkResult = checkJobs(cursor, args.state, kind, args.time, args.warning, args.critical) elif args.runTimeJobs: - checkResult = checkRunTimeJobs(cursor, args.name, args.state, args.time, args.warning, args.critical) + checkResult = checkRunTimeJobs(cursor, args.state, args.time, args.warning, args.critical) printNagiosOutput(checkResult) cursor.close()