Mailcow-CheckMK/local/share/check_mk/agents/special/agent_mailcow

246 lines
8.6 KiB
Plaintext
Raw Normal View History

2023-08-19 14:23:00 +02:00
#!/usr/bin/env python3
import getopt
import sys
import requests
import urllib3
import json
import os
from pprint import pprint
from requests.structures import CaseInsensitiveDict
from requests.auth import HTTPBasicAuth
def showUsage():
2023-08-19 14:53:19 +02:00
sys.stderr.write("""CheckMK Mailcow Special Agent
2023-08-19 14:23:00 +02:00
2023-08-19 14:53:19 +02:00
USAGE: agent_nextcloud -H [hostname] -k [apikey]
agent_nextcloud -h
2023-08-19 14:23:00 +02:00
OPTIONS:
-H, --hostname Hostname (FQDN or IP) of Nextcloud server
2023-08-19 14:53:19 +02:00
-k, --apikey API Key
2023-08-19 14:23:00 +02:00
-P, --port Port
--no-https True|False If "True": Disable HTTPS, use HTTP (not recommended!)
--no-cert-check True|False If "True": Disable TLS certificate check (not recommended!)
-h, --help Show this help message and exit
""")
2023-08-19 16:32:29 +02:00
# set this to True to produce debug output (this clutters the agent output)
2023-08-19 14:23:00 +02:00
# be aware: activating this logs very sensitive information to debug files in ~/tmp
# !!DO NOT FORGET to delete these files after debugging is done!!
2023-08-19 16:32:29 +02:00
DEBUG = False
2023-08-19 14:23:00 +02:00
2023-08-19 14:53:19 +02:00
mc_api_base = "api/v1/get"
2023-08-19 14:23:00 +02:00
opt_hostname = ""
2023-08-19 14:53:19 +02:00
opt_apikey = ""
2023-08-19 14:23:00 +02:00
opt_port = ""
opt_no_https = False
opt_no_cert_check = False
2023-08-19 14:53:19 +02:00
short_options = 'hH:k:P:'
2023-08-19 14:23:00 +02:00
long_options = [
2023-08-19 14:53:19 +02:00
'hostname=', 'apikey=', 'port=', 'no-https=', 'no-cert-check=', 'help'
2023-08-19 14:23:00 +02:00
]
2023-08-19 17:40:08 +02:00
domain_data = {}
mailbox_data = {}
2023-08-19 14:23:00 +02:00
def getOptions():
global opt_hostname
2023-08-19 14:53:19 +02:00
global opt_apikey
2023-08-19 14:23:00 +02:00
global opt_port
global opt_no_https
global opt_no_cert_check
opts, args = getopt.getopt(sys.argv[1:], short_options, long_options)
for opt, arg in opts:
if opt in ['-H', '--hostname']:
opt_hostname = arg
2023-08-19 14:53:19 +02:00
elif opt in ['-k', '--apikey']:
opt_apikey = arg
2023-08-19 14:23:00 +02:00
elif opt in ['-P', '--port']:
opt_port = arg
elif opt in ['--no-https']:
if arg == 'True':
opt_no_https = True
else:
opt_no_https = False
elif opt in ['--no-cert-check']:
if arg == 'True':
opt_no_cert_check = True
else:
opt_no_cert_check = False
elif opt in ['-h', '--help']:
showUsage()
sys.exit(0)
if DEBUG:
home_path = os.getenv("HOME")
tmp_path = f"{home_path}/tmp"
2023-08-19 14:53:19 +02:00
help_file = f"{tmp_path}/mailcow_{opt_hostname}_debug.txt"
2023-08-19 14:23:00 +02:00
with open(help_file, "a") as file:
file.write(f"Number of Arguments: {len(sys.argv)}, Argument List: {str(sys.argv)}\n")
2023-08-19 17:40:08 +02:00
2023-08-19 14:23:00 +02:00
def showOptions():
print(f"Hostname: {opt_hostname}")
2023-08-19 14:53:19 +02:00
print(f"Username: {opt_apikey}")
2023-08-19 14:23:00 +02:00
print(f"Port: {opt_port}")
print(f"No HTTPS: {opt_no_https}")
print(f"No TLS Check: {opt_no_cert_check}")
home_path = os.getenv("HOME")
tmp_path = f"{home_path}/tmp"
2023-08-19 14:53:19 +02:00
help_file = f"{tmp_path}/mailcow_{opt_hostname}_debug.txt"
2023-08-19 14:23:00 +02:00
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")
2023-08-19 17:40:08 +02:00
2023-08-19 16:32:29 +02:00
def getDomainInfo(headers, verify, base_url):
url = f"{base_url}/domain/all"
response = requests.get(url, headers=headers, verify=verify)
if (response.status_code == 200):
jsdata = response.text
data = json.loads(jsdata) # returns a list of dictionaries
i = 0
while i < len(data):
#pprint(data[i])
2023-08-19 17:40:08 +02:00
# get domain name and status (active (1) or not (0))
2023-08-19 16:32:29 +02:00
domain_name = data[i].get("domain_name")
2023-08-19 17:40:08 +02:00
active = data[i].get("active")
# get creation and last modification date
created = data[i].get("created")
modified = data[i].get("modified") # returns "None" or date
# get maximum and current number of mailboxes in this domain
2023-08-19 16:32:29 +02:00
max_num_mboxes_for_domain = data[i].get("max_num_mboxes_for_domain")
mboxes_in_domain = data[i].get("mboxes_in_domain")
2023-08-19 17:40:08 +02:00
# get maximum and current number of aliases in this domain
2023-08-19 16:32:29 +02:00
max_num_aliases_for_domain = data[i].get("max_num_aliases_for_domain")
2023-08-19 17:40:08 +02:00
aliases_in_domain = data[i].get("aliases_in_domain")
# get total messages in this domain
msgs_total = data[i].get("msgs_total")
# get total bytes used in this domain
bytes_total = data[i].get("bytes_total")
# get maximum quota for this domain
max_quota_for_domain = data[i].get("max_quota_for_domain")
2023-08-19 16:32:29 +02:00
i += 1
# return number of email domains
return i
else:
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
2023-08-19 17:40:08 +02:00
2023-08-19 16:32:29 +02:00
def getMailboxInfo(headers, verify, base_url):
url = f"{base_url}/mailbox/all"
response = requests.get(url, headers=headers, verify=verify)
if (response.status_code == 200):
jsdata = response.text
data = json.loads(jsdata) # returns a list of dictionaries
i = 0
global_num_messages = 0
while i < len(data):
#pprint(data[i])
2023-08-19 17:40:08 +02:00
# get status of mailbox (0-->inactive or 1-->active)
active = data[i].get("active")
2023-08-19 16:32:29 +02:00
# get username of mailbox
username = data[i].get("username")
2023-08-19 17:40:08 +02:00
# get friendly name of user
name = data[i].get("name")
2023-08-19 16:32:29 +02:00
# get number of messages in mailbox
num_messages = data[i].get("messages")
2023-08-19 17:40:08 +02:00
# get quota used in percent
percent_in_use = data[i].get("percent_in_use")
# get creation and last modification date
created = data[i].get("created")
modified = data[i].get("modified")
# get number of messages
messages = data[i].get("messages")
# get last login dates
last_imap_login = data[i].get("last_imap_login")
last_pop3_login = data[i].get("last_pop3_login")
last_smtp_login = data[i].get("last_smtp_login")
2023-08-19 16:32:29 +02:00
i += 1
global_num_messages += num_messages
# return number of mailboxes and global number of messages
return i, global_num_messages
else:
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
2023-08-19 17:40:08 +02:00
2023-08-19 16:32:29 +02:00
def getMailcowInfo(headers, verify, base_url):
url = f"{base_url}/status/version"
response = requests.get(url, headers=headers, verify=verify)
if (response.status_code == 200):
jsdata = response.text
data = json.loads(jsdata) # returns a dictionary
#pprint(data)
# get Mailcow version
mc_version = data["version"]
return mc_version
else:
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
2023-08-19 14:23:00 +02:00
def main():
getOptions()
2023-08-19 16:32:29 +02:00
# do some parameter checks
2023-08-19 14:23:00 +02:00
if (opt_hostname == ""):
sys.stderr.write(f"No hostname given.\n")
showUsage()
sys.exit(1)
2023-08-19 16:32:29 +02:00
else:
hostname = opt_hostname
2023-08-19 14:53:19 +02:00
if (opt_apikey == ""):
sys.stderr.write(f"No API key given.\n")
showUsage()
sys.exit(1)
2023-08-19 14:23:00 +02:00
if (opt_no_cert_check):
2023-08-19 16:32:29 +02:00
# disable certificate warnings
2023-08-19 14:23:00 +02:00
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
verify = False
else:
verify = True
if (opt_port == ""):
if (opt_no_https):
protocol = "http"
port = "80"
else:
protocol = "https"
port = "443"
else:
if (opt_no_https):
protocol = "http"
else:
protocol = "https"
port = opt_port
if (protocol == "http" and port == "443"):
sys.stderr.write(f"Combining HTTP with port 443 is not supported.\n")
sys.exit(1)
if (protocol == "https" and port == "80"):
sys.stderr.write(f"Combining HTTPS with port 80 is not supported.\n")
2023-08-19 16:32:29 +02:00
sys.exit(1)
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
headers["X-API-Key"] = opt_apikey
# now "hostname" contains the FQDN of the host running Mailcow
# now "protocol" is http or https
# 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
if DEBUG:
showOptions()
print(f"hostname: {hostname}, protocol: {protocol}, port: {port}, verify: {verify}")
base_url = f"{protocol}://{hostname}:{port}/{mc_api_base}"
# get domain data
num_domains = getDomainInfo(headers, verify, base_url)
# get mailbox data
num_mailboxes, num_global_messages = getMailboxInfo(headers, verify, base_url)
# get global Mailcow info
mailcow_version = getMailcowInfo(headers, verify, base_url)
2023-08-19 14:23:00 +02:00
if __name__ == "__main__":
main()