added debug decorator function and type hints

This commit is contained in:
mellis 2024-01-17 15:15:55 +01:00
parent 577b459e9c
commit 13258ae201
1 changed files with 88 additions and 14 deletions

View File

@ -9,8 +9,11 @@ import os
from pprint import pprint
from requests.structures import CaseInsensitiveDict
from requests.auth import HTTPBasicAuth
from time import (
time, localtime, strftime,
)
def showUsage():
def showUsage() -> None:
sys.stderr.write("""CheckMK Mailcow Special Agent
USAGE: agent_nextcloud -H [hostname] -k [apikey]
@ -47,8 +50,73 @@ long_options = [
domain_data = {}
mailbox_data = {}
debugLogFilename = ""
SEP = "|"
#SEP = "\t"
TIMEFMT = "%Y-%m-%d %H:%M:%S"
FLOATFMT = "{:.4f}"
def getOptions():
'''
Decorator function for debugging purposes
creates a file with many information regarding the function call, like:
timestamp
name of function
runtime
number of arguments
number of keyword arguments
return value of function call
type of return value
all parameters given to function
'''
def debugLog(function):
def wrapper(*args, **kwargs):
# execute function and measure runtime
start = time()
value = function(*args, **kwargs)
end = time()
# get number of args and kwargs
len_args = len(args)
len_kwargs = len(kwargs)
# format the output
seconds = FLOATFMT.format(end - start)
local_time = strftime(TIMEFMT,localtime(start))
# get function name
fname = function.__name__
# create output
# out1: Timestamp|Name of Function|Runtime|Num Args|Num Kwargs|Return Value|Return Value Type
out1 = f"{local_time}{SEP}{fname}{SEP}{seconds}{SEP}{len_args}{SEP}{len_kwargs}{SEP}{value}{SEP}{type(value)}"
# out2: all arguments
out2 = ""
for arg in args:
out2 = out2 + SEP + str(arg)
# out 3: all keyword arguments
out3 = ""
if len_kwargs > 0:
for key, val in kwargs.items():
out3 = out3 + SEP + key + ":" + str(val)
# write output to file
if debugLogFilename != "":
try:
with open(debugLogFilename, "a+") as f:
f.write(f"{out1}{out2}{out3}\n")
except:
sys.stderr.write(f"Something went wrong when writing to file {debugLogFilename}\n")
sys.exit(1)
else:
sys.stderr.write(f"Debug activated, but no debug filename given.\n")
sys.exit(1)
return value
return wrapper
def getDebugFilename(hostname: str) -> str:
home_path = os.getenv("HOME")
tmp_path = f"{home_path}/tmp"
file_name = f"{tmp_path}/mailcow_{hostname}_debug.log"
return file_name
def getOptions() -> None:
global opt_hostname
global opt_apikey
global opt_port
@ -84,7 +152,8 @@ def getOptions():
file.write(f"Number of Arguments: {len(sys.argv)}, Argument List: {str(sys.argv)}\n")
def showOptions():
#@debugLog
def showOptions() -> None:
print(f"Hostname: {opt_hostname}")
print(f"Username: {opt_apikey}")
print(f"Port: {opt_port}")
@ -96,8 +165,8 @@ def showOptions():
with open(help_file, "a") as file:
file.write(f"Hostname: {opt_hostname}, Port: {opt_port}, No HTTPS: {opt_no_https}, No Cert Check: {opt_no_cert_check}\n")
def getDomainInfo(headers, verify, base_url):
#@debugLog
def getDomainInfo(headers: str, verify: bool, base_url: str) -> int:
url = f"{base_url}/domain/all"
response = requests.get(url, headers=headers, verify=verify)
if (response.status_code == 200):
@ -146,8 +215,8 @@ def getDomainInfo(headers, verify, base_url):
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
def getMailboxInfo(headers, verify, base_url):
#@debugLog
def getMailboxInfo(headers: str, verify: bool, base_url: str) -> tuple:
url = f"{base_url}/mailbox/all"
response = requests.get(url, headers=headers, verify=verify)
if (response.status_code == 200):
@ -202,8 +271,8 @@ def getMailboxInfo(headers, verify, base_url):
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
def getMailcowInfo(headers, verify, base_url):
#@debugLog
def getMailcowInfo(headers: str, verify: bool, base_url: str) -> str:
url = f"{base_url}/status/version"
response = requests.get(url, headers=headers, verify=verify)
if (response.status_code == 200):
@ -217,7 +286,8 @@ def getMailcowInfo(headers, verify, base_url):
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
def getSolrInfo(headers, verify, base_url):
#@debugLog
def getSolrInfo(headers: str, verify: bool, base_url: str) -> tuple:
url = f"{base_url}/status/solr"
response = requests.get(url, headers=headers, verify=verify)
if (response.status_code == 200):
@ -255,7 +325,8 @@ user2@dom1.de;1;2022-04-29 14:38:33;2022-04-29 14:38:33;Tom;271;0;21474836480;25
user1@dom2.de;1;2022-04-30 09:55:37;2022-04-30 09:55:37;Melissa;53460;33;19964887040;6677677548;1692520066;0;1692510822
'''
def doCmkOutputMailboxes():
#@debugLog
def doCmkOutputMailboxes() -> None:
print("<<<mailcow_mailboxes:sep(59)>>>")
for mb in mailbox_data:
active = mailbox_data[mb]["active"]
@ -273,8 +344,8 @@ def doCmkOutputMailboxes():
last_smtp_login = mailbox_data[mb]["last_smtp_login"]
print(f"{mb};{active};{created};{modified};{name};{num_messages};{percent_in_use};{quota};{quota_used};{last_imap_login};{last_pop3_login};{last_smtp_login}")
def doCmkOutputMailcow(version, num_domains, num_mailboxes, num_global_messages, solr_enabled, solr_size, solr_documents):
#@debugLog
def doCmkOutputMailcow(version: str, num_domains: int, num_mailboxes: int, num_global_messages: int, solr_enabled: bool, solr_size: float, solr_documents: int) -> None:
print("<<<mailcow_info:sep(59)>>>")
# strip semicolons, if present, since we use it as delimiter
version = version.replace(";", "")
@ -301,7 +372,8 @@ dom2.de;1;2022-04-29 13:38:42;2023-08-19 17:21:04;10;0;400;2;0;0;10737418240
dom3.de;1;2022-04-29 13:36:08;2022-04-29 21:26:19;10;1;100;3;28132;12852485367;21474836480
'''
def doCmkOutputDomains():
#@debugLog
def doCmkOutputDomains() -> None:
print("<<<mailcow_domains:sep(59)>>>")
for dom in domain_data:
active = domain_data[dom]["active"]
@ -318,6 +390,7 @@ def doCmkOutputDomains():
def main():
global debugLogFilename
getOptions()
# do some parameter checks
if (opt_hostname == ""):
@ -363,6 +436,7 @@ def main():
# now "port" contains the port number to use
# now "verify" signals whether certificate checking will be done (True) or not (False)
# now "headers" contains the accepted format (JSON) and the API key to use
debugLogFilename = getDebugFilename(hostname)
if DEBUG:
showOptions()
print(f"hostname: {hostname}, protocol: {protocol}, port: {port}, verify: {verify}")