updated
This commit is contained in:
parent
6f5e1f59d0
commit
cd758de656
@ -69,192 +69,19 @@ def isOnline(host: str, timeout: int) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def log(config: dict) -> None:
|
||||
def log(host: int, timeout: int, no_stdout: bool, log_path: None | str = None) -> 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"
|
||||
|
||||
if config['log'] != None:
|
||||
with open(config['log'], 'a') as file:
|
||||
if log_path is not None:
|
||||
with open(log_path, 'a') as file:
|
||||
file.write(logline)
|
||||
|
||||
if config['stdout']:
|
||||
if not no_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 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 parseArgs(args: list[str]):
|
||||
import argparse
|
||||
|
||||
@ -264,27 +91,12 @@ def parseArgs(args: list[str]):
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
parser_outages = subparsers.add_parser(
|
||||
'outages', help='Print outages', formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
||||
)
|
||||
parser_outages.add_argument(
|
||||
'log_path', type=str, default='./connection.log',
|
||||
help='Path to a file with connection logs.'
|
||||
)
|
||||
parser_outages.add_argument(
|
||||
'--time', type=int, default=3,
|
||||
help='Minimum duration for a connection loss to be considered an outage.'
|
||||
)
|
||||
|
||||
# Arguments for the log command
|
||||
parser_log = subparsers.add_parser(
|
||||
'log', help='Log the connection status.', formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
||||
)
|
||||
parser_log.add_argument(
|
||||
'--config', type=str, default='./config.json',
|
||||
help='Path to a config file in JSON format.'
|
||||
)
|
||||
parser_log.add_argument(
|
||||
'--path', type=str, default='./connection.json',
|
||||
'--path', type=str, default=None,
|
||||
help='Path to a the file where results should be appended to. Creates the file if it does not exist.'
|
||||
)
|
||||
parser_log.add_argument(
|
||||
@ -300,7 +112,21 @@ def parseArgs(args: list[str]):
|
||||
help='A flag that disables printing to stdout.'
|
||||
)
|
||||
|
||||
parser.parse_args(args)
|
||||
# Arguments for the outages command
|
||||
parser_outages = subparsers.add_parser(
|
||||
'outages', help='Print outages', formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
||||
)
|
||||
parser_outages.add_argument(
|
||||
'--log-path', type=str, default='./connection.log',
|
||||
help='Path to a file with connection logs.'
|
||||
)
|
||||
parser_outages.add_argument(
|
||||
'--time', type=int, default=3,
|
||||
help='Minimum duration for a connection loss to be considered an outage.'
|
||||
)
|
||||
|
||||
print(parser.parse_args(args))
|
||||
|
||||
|
||||
def main():
|
||||
from sys import argv
|
||||
|
Loading…
Reference in New Issue
Block a user