save work

This commit is contained in:
Kristian Krsnik 2023-08-30 13:17:19 +02:00
parent 7d73544d0a
commit 985aa9888d

View File

@ -1,6 +1,8 @@
import sys
import json
import argparse
from datetime import datetime
from typing import Any
import requests
@ -69,198 +71,57 @@ def isOnline(host: str, timeout: int) -> bool:
return False
def log(config: dict) -> None:
def log(path: str, host: str, timeout: int, stdout: bool) -> None:
"""Log the connection status of a host"""
logline = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}][{config['host']}][{'OK' if isOnline(config['host'], config['timeout']) else 'FAIL'}]\n"
logline = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}][{host}][{'OK' if isOnline(host, timeout) else 'FAIL'}]\n"
# TODO don't print to log path when no path is given
if config['log'] != None:
with open(config['log'], 'a') as file:
with open(path, 'a') as file:
file.write(logline)
if config['stdout']:
if stdout:
print(logline)
def printHelp() -> None:
"""Prints the help menu"""
print(
"""
If no argument is passed then de defaults are assumed.
--config Path to a config file in JSON format.
To set a command line argument, use it as a key and set its value.
Config is nor used unless explicitly set.
--log Path to a the file where results should be appended to.
Created the file if it does not already exist.
Default: ./connection.log
--host IP or hostname of a server to query.
Default: 1.1.1.1
--timeout Set the timeout in seconds to use for the connection test
Default: 2
--outages Print the outages to stdout.
Set the lenght in minutes where a connection loss is condidered an outage
This option can only be used with --log.
Default: 3
--stdout Return the resulting logline in the terminal.
Default Behaviour: Do not print to stdout.
--help Print this menu
"""
)
def cliLog(args: Any) -> None:
# TODO read config file
log(args.path, args.host, args.timeout, args.stdout)
def loadConfig() -> tuple[dict, str]:
"""Load and validate the config and return it as a dict together with the execution mode"""
argv = sys.argv
config: dict = {}
buffer = ''
mode = 'log'
# parse arguments
for arg in argv[1:]:
if arg.startswith('--'):
buffer = arg.removeprefix('--')
config[buffer] = []
else:
config[buffer].append(arg)
# print help if requested
if 'help' in config:
printHelp()
quit()
## Validate Arguments ##
# right arguments
valid_parameters = {'config', 'log', 'host',
'timeout', 'outages', 'stdout', 'help'}
if (unknown_parameters := config.keys() - valid_parameters) != set():
print(f"[ERROR] Unknown parameters: {unknown_parameters}")
printHelp()
quit()
# number of arguments
maximum_arguments = {
'config': 1,
'log': 1,
'host': 1,
'timeout': 1,
'outages': 1,
'stdout': 0,
'help': 0
}
for key in config:
if len(config[key]) > maximum_arguments[key]:
print(
f"[ERROR] Too many arguments for '{key}'. Expected 0{' or 1' if maximum_arguments[key] == 1 else ''}. Got: {len(config[key])}")
printHelp()
quit()
# check that outages is only used with --log
if 'outages' in config:
mode = 'outages'
if config.keys() - {'outages', 'log'} != set():
print(
f"[ERROR] --outages can only be used alone or with --log")
printHelp()
quit()
# After that check has passed remove the list
for key in config:
config[key] = config[key][0] if len(config[key]) == 1 else None
# set stdout
config['stdout'] = 'stdout' in config
# if config is passed then load it
if 'config' in config:
try:
config_file = './config.json' if config['config'] == None else config['config']
with open(config_file, 'r') as file:
# this gives the stdout toggle behaviour
config_file = json.load(file)
# merge config_file and config
# this also subtly overrites no-stdout to whatever the config file says
for key in config_file.keys() & config.keys():
if key == 'stdout':
continue
if config[key] == None:
config[key] = config_file[key]
config_file.update(config)
config = config_file
except FileNotFoundError:
print(f"[ERROR] Config file not found: {config['config']}")
printHelp()
quit()
# load defaults, if not set
defaults = {
'log': './connection.log',
'host': '1.1.1.1',
'timeout': 2,
'outages': 3,
'stdout': False,
'help': None
}
for key in defaults:
if key == 'log':
if config['stdout'] and 'log' not in config:
config['log'] = None
continue
if (key not in config) or (key in config and config[key] == None):
config[key] = defaults[key]
# timeout
try:
config['timeout'] = int(config['timeout'])
except ValueError:
print(
f"[ERROR] Invalid type for 'timeout'. Expected int. Got: {type(config['timeout'])}")
printHelp()
quit()
if config['timeout'] <= 0:
print(f"[ERROR] 'timeout' needs to be larger than 0")
printHelp()
quit()
# outages
try:
config['outages'] = int(config['outages'])
except ValueError:
print(
f"[ERROR] Invalid type for 'outages'. Expected int. Got: {type(config['outages'])}")
printHelp()
quit()
if config['outages'] < 0:
print(f"[ERROR] 'outages' needs to be larger than 0")
printHelp()
quit()
return config, mode
def cliPOutages(args: Any) -> None:
printOutages(args.path, args.min_duration)
def main():
config, mode = loadConfig()
if mode == 'log':
log(config)
elif mode == 'outages':
printOutages(config)
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
parser_log = subparsers.add_parser('log')
parser_log.add_argument('--config', type=argparse.FileType('w', encoding='UTF-8'), default='./config.json',
help='Path to a config file in JSON format. To set a command line argument, use it as a key and set its value. Config is not used unless explicitly set.')
parser_log.add_argument('--path', type=str, default='./connection.log',
help='Path to a the file where results should be appended to. Created the file if it does not already exist.')
parser_log.add_argument('--host', type=str, default='1.1.1.1',
help='IP or hostname of a server to query.')
parser_log.add_argument('--timeout', type=int,
default=2, help='Timeout in seconds.')
parser_log.add_argument('--stdout', default=False,
action='store_true', help='Print the logline to stdout.')
parser_log.set_defaults(func=printOutages)
parser_outages = subparsers.add_parser('outages')
parser_outages.add_argument('--min-duration', type=int, default=3,
help='Set the minimum duration in minutes where a connection loss is condidered an outage.')
parser_outages.add_argument(
'--path', type=str, default='./connection.log', help='Path to the file with outage data.')
parser_outages.set_defaults(func=printOutages)
args = parser.parse_args()
# args.func(args)
print(args)
if __name__ == '__main__':