Compare commits

..

3 commits

Author SHA1 Message Date
Benjamin Renard
44bd9a6446
Telltale: add check_entrypoint() to easily implement Icinga checker script 2023-07-10 11:56:03 +02:00
Benjamin Renard
f8602801d7
Fix some pylint warnings 2023-07-10 11:55:09 +02:00
Benjamin Renard
e8572e2eaa
pre-commit: bump to isort 5.11.5 2023-07-10 11:53:42 +02:00
7 changed files with 210 additions and 18 deletions

View file

@ -12,7 +12,7 @@ repos:
- id: black - id: black
args: ['--target-version', 'py37', '--line-length', '100'] args: ['--target-version', 'py37', '--line-length', '100']
- repo: https://github.com/PyCQA/isort - repo: https://github.com/PyCQA/isort
rev: 5.11.4 rev: 5.11.5
hooks: hooks:
- id: isort - id: isort
args: ['--profile', 'black', '--line-length', '100'] args: ['--profile', 'black', '--line-length', '100']

View file

@ -62,3 +62,26 @@ def pretty_format_list(row, encoding="utf8", prefix=None):
+ pretty_format_value_in_list(values, encoding=encoding, prefix=prefix) + pretty_format_value_in_list(values, encoding=encoding, prefix=prefix)
) )
return "\n".join(result) return "\n".join(result)
def pretty_format_timedelta(timedelta):
"""Format timedelta object"""
seconds = int(timedelta.total_seconds())
if seconds < 1:
return "less than one second"
periods = [
("year", 60 * 60 * 24 * 365),
("month", 60 * 60 * 24 * 30),
("day", 60 * 60 * 24),
("hour", 60 * 60),
("minute", 60),
("second", 1),
]
strings = []
for period_name, period_seconds in periods:
if seconds >= period_seconds:
period_value, seconds = divmod(seconds, period_seconds)
strings.append(f'{period_value} {period_name}{"s" if period_value > 1 else ""}')
return ", ".join(strings)

View file

@ -37,11 +37,13 @@ def get_default_opt_value(config, default_config, key):
return default_config.get(key) return default_config.get(key)
def get_opts_parser(desc=None, just_try=False, just_one=False, progress=False, config=None): def get_opts_parser(
desc=None, just_try=False, just_one=False, progress=False, config=None, **kwargs
):
"""Retrieve options parser""" """Retrieve options parser"""
default_config = dict(logfile=None) default_config = {"logfile": None}
parser = argparse.ArgumentParser(description=desc) parser = argparse.ArgumentParser(description=desc, **kwargs)
parser.add_argument( parser.add_argument(
"-v", "--verbose", action="store_true", dest="verbose", help="Enable verbose mode" "-v", "--verbose", action="store_true", dest="verbose", help="Enable verbose mode"
@ -91,20 +93,20 @@ def add_email_opts(parser, config=None, **defaults):
"""Add email options""" """Add email options"""
email_opts = parser.add_argument_group("Email options") email_opts = parser.add_argument_group("Email options")
default_config = dict( default_config = {
smtp_host="127.0.0.1", "smtp_host": "127.0.0.1",
smtp_port=25, "smtp_port": 25,
smtp_ssl=False, "smtp_ssl": False,
smtp_tls=False, "smtp_tls": False,
smtp_user=None, "smtp_user": None,
smtp_password=None, "smtp_password": None,
smtp_debug=False, "smtp_debug": False,
email_encoding=sys.getdefaultencoding(), "email_encoding": sys.getdefaultencoding(),
sender_name=getpass.getuser(), "sender_name": getpass.getuser(),
sender_email=f"{getpass.getuser()}@{socket.gethostname()}", "sender_email": f"{getpass.getuser()}@{socket.gethostname()}",
catch_all=False, "catch_all": False,
templates_path=None, "templates_path": None,
) }
default_config.update(defaults) default_config.update(defaults)
email_opts.add_argument( email_opts.add_argument(

View file

@ -0,0 +1,12 @@
""" Test telltale file """
import logging
from mylib.scripts.telltale_test import default_filepath
from mylib.telltale import TelltaleFile
log = logging.getLogger(__name__)
def main(argv=None):
"""Script main"""
TelltaleFile.check_entrypoint(argv=argv, default_filepath=default_filepath)

View file

@ -0,0 +1,40 @@
""" Test telltale file """
import logging
import os.path
import sys
import tempfile
from mylib.scripts.helpers import get_opts_parser, init_logging
from mylib.telltale import TelltaleFile
log = logging.getLogger(__name__)
default_filepath = os.path.join(tempfile.gettempdir(), f"{__name__}.last")
def main(argv=None):
"""Script main"""
if argv is None:
argv = sys.argv[1:]
# Options parser
parser = get_opts_parser()
options = parser.parse_args()
parser.add_argument(
"-p",
"--telltale-file-path",
action="store",
type=str,
dest="telltale_file_path",
help=f"Telltale file path (default: {default_filepath})",
default=default_filepath,
)
options = parser.parse_args()
# Initialize logs
init_logging(options, __doc__)
telltale_file = TelltaleFile(filepath=options.telltale_file_path)
telltale_file.update()

View file

@ -1,11 +1,19 @@
""" Telltale files helpers """ """ Telltale files helpers """
import argparse
import datetime import datetime
import logging import logging
import os import os
import sys
from mylib import pretty_format_timedelta
from mylib.scripts.helpers import get_opts_parser, init_logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
DEFAULT_WARNING_THRESHOLD = 90
DEFAULT_CRITICAL_THRESHOLD = 240
class TelltaleFile: class TelltaleFile:
"""Telltale file helper class""" """Telltale file helper class"""
@ -50,3 +58,108 @@ class TelltaleFile:
return True return True
except FileNotFoundError: except FileNotFoundError:
return True return True
@classmethod
def check_entrypoint(
cls,
argv=None,
description=None,
default_filepath=None,
default_warning_threshold=None,
default_critical_threshold=None,
fail_message=None,
success_message=None,
):
"""Entry point of the script to check a telltale file last update"""
argv = argv if argv else sys.argv
description = description if description else "Check last execution date"
parser = get_opts_parser(desc=description, exit_on_error=False)
parser.add_argument(
"-p",
"--telltale-file-path",
action="store",
type=str,
dest="telltale_file_path",
help=f"Telltale file path (default: {default_filepath})",
default=default_filepath,
required=not default_filepath,
)
default_warning_threshold = (
default_warning_threshold
if default_warning_threshold is not None
else DEFAULT_WARNING_THRESHOLD
)
default_critical_threshold = (
default_critical_threshold
if default_critical_threshold is not None
else DEFAULT_CRITICAL_THRESHOLD
)
parser.add_argument(
"-w",
"--warning",
type=int,
dest="warning",
help=(
"Specify warning threshold (in minutes, default: "
f"{default_warning_threshold} minutes)"
),
default=default_warning_threshold,
)
parser.add_argument(
"-c",
"--critical",
type=int,
dest="critical",
help=(
"Specify critical threshold (in minutes, default: "
f"{default_critical_threshold} minutes)"
),
default=default_critical_threshold,
)
try:
options = parser.parse_args(argv[1:])
except argparse.ArgumentError as err:
print(f"UNKNOWN - {err}")
sys.exit(3)
# Initialize logs
init_logging(options, argv[0])
telltale_file = cls(filepath=options.telltale_file_path)
last = telltale_file.last_update
if not last:
status = "UNKNOWN"
exit_code = 3
msg = (
fail_message
if fail_message
else "Fail to retrieve last successful date of execution"
)
else:
delay = datetime.datetime.now() - last
msg = (
success_message
if success_message
else "Last successful execution was {last_delay} ago ({last_date})"
).format(
last_delay=pretty_format_timedelta(delay),
last_date=last.strftime("%Y/%m/%d %H:%M:%S"),
)
if delay >= datetime.timedelta(minutes=options.critical):
status = "CRITICAL"
exit_code = 2
elif delay >= datetime.timedelta(minutes=options.warning):
status = "WARNING"
exit_code = 1
else:
status = "OK"
exit_code = 0
print(f"{status} - {msg}")
sys.exit(exit_code)

View file

@ -69,6 +69,8 @@ setup(
"mylib-test-report = mylib.scripts.report_test:main", "mylib-test-report = mylib.scripts.report_test:main",
"mylib-test-ldap = mylib.scripts.ldap_test:main", "mylib-test-ldap = mylib.scripts.ldap_test:main",
"mylib-test-sftp = mylib.scripts.sftp_test:main", "mylib-test-sftp = mylib.scripts.sftp_test:main",
"mylib-test-telltale = mylib.scripts.telltale_test:main",
"mylib-test-telltale-check = mylib.scripts.telltale_check_test:main",
], ],
}, },
) )