#!/usr/bin/env python3 import time import random from pprint import pprint from .agent_based_api.v1 import get_value_store, get_rate, register, render, Service, Result, State, Metric def getStateUpper(levels, value): warn, crit = levels if value >= crit: return State.CRIT if value >= warn: return State.WARN return State.OK def discover_mailcow_mailboxes(section): for key in section: yield(Service(item = key)) def check_mailcow_mailboxes(item, params, section): mailbox = item # get all values from section active = section[mailbox][0] create_time = section[mailbox][1] modify_time = section[mailbox][2] display_name = section[mailbox][3] number_of_messages = section[mailbox][4] _percent_in_use = section[mailbox][5] quota = section[mailbox][6] total_number_of_bytes_used = section[mailbox][7] percent_storage_used_for_messages = section[mailbox][8] last_imap_login_data = section[mailbox][9] last_pop3_login_data = section[mailbox][10] last_smtp_login_data = section[mailbox][11] # create (main) service for used storage (mailbox quota) warn, crit = params["levels_mailcow_mailboxes_quota_used"] levels = (warn, crit) state_quota = getStateUpper(levels, percent_storage_used_for_messages) # create graph for used quota yield Metric("mailcow_mailboxes_used_quota", percent_storage_used_for_messages, levels=levels) summary_quota = f"Storage quota for mailbox of '{display_name}' is {render.percent(percent_storage_used_for_messages)}" details_quota = f"Quota: {render.bytes(total_number_of_bytes_used)} of {render.bytes(quota)} used" # create service yield(Result(state=state_quota, summary=summary_quota, details=details_quota)) # create some additional services and information only details notice = f"Active: {active}" yield(Result(state=State.OK, notice=notice)) notice = f"Creation date: {create_time}" yield(Result(state=State.OK, notice=notice)) notice = f"Last modified: {modify_time}" yield(Result(state=State.OK, notice=notice)) notice = f"Last IMAP login: {last_imap_login_data} ago" yield(Result(state=State.OK, notice=notice)) notice = f"Last POP3 login: {last_pop3_login_data} ago" yield(Result(state=State.OK, notice=notice)) notice = f"Last SMTP login: {last_smtp_login_data} ago" yield(Result(state=State.OK, notice=notice)) # create service for number of messages warn, crit = params["levels_mailcow_mailboxes_num_messages"] levels = (warn, crit) state_messages = getStateUpper(levels, number_of_messages) yield Metric("mailcow_mailboxes_messages", number_of_messages, levels=levels) notice = f"Number of messages: {number_of_messages}" yield(Result(state=state_messages, notice=notice)) def parse_mailcow_mailboxes_section(string_table): # convert the raw output of the agent section into a meaningful structure, do type conversions and so on parsed_data = {} for line in string_table: mailboxname = line[0] value_active = int(line[1]) if value_active == 1: active = "yes" else: active = "no" # calculate creation and last modification date in human readable format create_time_value = line[2] if create_time_value == "None": create_time_data = "Not available" else: create_time_data = create_time_value modify_time_value = line[3] if modify_time_value == "None": modify_time_data = "Never" else: modify_time_data = modify_time_value # get display name display_name = line[4] # number of messages within mailbox number_of_messages = int(line[5]) # calculate storage used for all messages in mailbox quota = int(line[7]) total_number_of_bytes_used = int(line[8]) if quota == 0: # quota is not set, if this is the case, line[6] contains no numeric value, but the char "-" # so set all usage counters to zero percent_in_use = 0 percent_storage_used_for_messages = 0 else: # percent in use, rounded to full percent (calculated by Mailcow) percent_in_use = int(line[6]) # let's calculate our own value percent_storage_used_for_messages = total_number_of_bytes_used * 100 / quota # get time of last login for IMAP/POP3/SMTP (seconds since epoch) last_imap_login = int(line[9]) last_pop3_login = int(line[10]) last_smtp_login = int(line[11]) # transfer these times into a human friendly format if last_imap_login == 0: last_imap_login_data = "Never" else: curr_time = int(time.time()) diff_time = curr_time - last_imap_login last_imap_login_data = render.timespan(diff_time) if last_pop3_login == 0: last_pop3_login_data = "Never" else: curr_time = int(time.time()) diff_time = curr_time - last_pop3_login last_pop3_login_data = render.timespan(diff_time) if last_smtp_login == 0: last_smtp_login_data = "Never" else: curr_time = int(time.time()) diff_time = curr_time - last_smtp_login last_smtp_login_data = render.timespan(diff_time) # store all (calculated) data parsed_data[f"{mailboxname}"] = [active, create_time_data, modify_time_data, display_name, number_of_messages, percent_in_use, quota, total_number_of_bytes_used, percent_storage_used_for_messages, last_imap_login_data, last_pop3_login_data, last_smtp_login_data ] return parsed_data register.agent_section( name = "mailcow_mailboxes", parse_function = parse_mailcow_mailboxes_section, ) register.check_plugin( name = "mailcow_mailboxes", service_name = "Mailcow mailbox %s", discovery_function = discover_mailcow_mailboxes, check_function = check_mailcow_mailboxes, check_default_parameters = { "levels_mailcow_mailboxes_quota_used": (65.0, 85.0), "levels_mailcow_mailboxes_num_messages": (1000, 2500), }, check_ruleset_name="mailcow_mailboxes", )