diff --git a/check_mk-azure-keyvault/local/lib/check_mk/base/plugins/agent_based/azure_keyvault.py b/check_mk-azure-keyvault/local/lib/check_mk/base/plugins/agent_based/azure_keyvault.py new file mode 100644 index 0000000..63f8153 --- /dev/null +++ b/check_mk-azure-keyvault/local/lib/check_mk/base/plugins/agent_based/azure_keyvault.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# Copyright (C) 2023 Spearhead Systems SRL - License: GNU General Public License v2 + +import json +from datetime import datetime, timezone +from cmk.base.plugins.agent_based.agent_based_api.v1 import register, Result, Service, State + + +# Convert JSON entries into dictionaries indexed by certificate name. +def parse_keyvault(string_table): + raw_json = "" + cert_data = [] + + for row in string_table: + line = row[0] + raw_json += line + if line == "]": + cert_data.extend(json.loads(raw_json)) + raw_json = "" + + lookup = {} + for cert in cert_data: + lookup[cert["name"]] = cert + + return lookup + + +register.agent_section( + name="azure_keyvault", + parse_function=parse_keyvault +) + + +# Produce a list of certificates based on the parsed output. +def discover_keyvault(section): + for name, details in sorted(section.items()): + yield Service(item=name) + + +# Given a specific certificate, look it up in the parsed output, and produce +# results on that service based upon the certificate's expiry. +def check_keyvault(item, params, section): + warn_days = params.get("warn_days") + crit_days = params.get("crit_days") + + cert = section.get(item) + if cert is None: + return + + expires = datetime.fromisoformat(cert["attributes"]["expires"]) + now = datetime.now(timezone.utc) + remaining_days = (expires - now).days + + state = State.OK + if crit_days is not None and remaining_days < crit_days: + state = State.CRIT + elif warn_days is not None and remaining_days < warn_days: + state = State.WARN + + yield Result(state=state, summary="Expires in %d days" % remaining_days) + + +register.check_plugin( + name="azure_keyvault", + service_name="Azure Keyvault Certificate %s", + + check_function=check_keyvault, + check_default_parameters={}, + check_ruleset_name="azure_keyvault", + + discovery_function=discover_keyvault, +) diff --git a/check_mk-azure-keyvault/local/share/check_mk/agents/special/agent_azure_keyvault b/check_mk-azure-keyvault/local/share/check_mk/agents/special/agent_azure_keyvault new file mode 100755 index 0000000..c594dcd --- /dev/null +++ b/check_mk-azure-keyvault/local/share/check_mk/agents/special/agent_azure_keyvault @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright (C) 2023 Spearhead Systems SRL - License: GNU General Public License v2 + +az=/usr/bin/az + +set -euo pipefail + +if [ "$#" -lt 4 ]; then + echo "Usage: $0 ... [vaultN]" >&2 + exit 1 +fi + +tenant="$1" +user="$2" +password="$3" +vaults="${@:4}" + +echo "<<>>" + +"$az" login --service-principal --tenant="$tenant" --user="$user" --password="$password" > /dev/null + +for vault in $vaults; do + "$az" keyvault certificate list --vault-name="$vault" +done + +"$az" logout diff --git a/check_mk-azure-keyvault/local/share/check_mk/checks/agent_azure_keyvault b/check_mk-azure-keyvault/local/share/check_mk/checks/agent_azure_keyvault new file mode 100644 index 0000000..813cbe0 --- /dev/null +++ b/check_mk-azure-keyvault/local/share/check_mk/checks/agent_azure_keyvault @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# Copyright (C) 2023 Spearhead Systems SRL - License: GNU General Public License v2 + +def agent_azure_keyvault(params, hostname, ipaddress): + tenant = params["tenant"] + client = params["client"] + secret = params["secret"] + + args = [tenant, client, secret] + + for vault in params["vaults"]: + args.extend([vault.strip()]) + + return args + +special_agent_info["azure_keyvault"] = agent_azure_keyvault diff --git a/check_mk-azure-keyvault/local/share/check_mk/web/plugins/wato/azure_keyvault.py b/check_mk-azure-keyvault/local/share/check_mk/web/plugins/wato/azure_keyvault.py new file mode 100644 index 0000000..aba613a --- /dev/null +++ b/check_mk-azure-keyvault/local/share/check_mk/web/plugins/wato/azure_keyvault.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# Copyright (C) 2023 Spearhead Systems SRL - License: GNU General Public License v2 + +import copy +from cmk.gui.i18n import _ +from cmk.gui.plugins.wato.utils import ( + rulespec_registry, + HostRulespec, + IndividualOrStoredPassword, + RulespecGroupCheckParametersDiscovery, + CheckParameterRulespecWithItem, + RulespecGroupCheckParametersApplications, +) +from cmk.gui.watolib.rulespecs import Rulespec +from cmk.gui.valuespec import ( + Dictionary, + TextInput, + Integer, + ListOfStrings, + Password +) + + +def _valuespec_special_agents_azure_keyvault_check(): + return Dictionary( + title=_("Azure Key Vault Certificate Checks"), + optional_keys=["warn_days", "crit_days"], + elements=[ + ( + "warn_days", + Integer( + minvalue=0, + default_value=30, + title=_("Certificate Days to Warn"), + help=_( + "How many days to warn before a certificate in this key vault will expire" + ), + ), + ), + ( + "crit_days", + Integer( + minvalue=0, + default_value=3, + title=_("Certificate Days to Crit"), + help=_( + "How many days to crit before a certificate in this key vault will expire" + ), + ), + ), + ], + ) + +def _valuespec_special_agents_azure_keyvault_discovery(): + return Dictionary( + title=_("Azure Key Vault Certificate Discovery"), + elements=[ + ( + "tenant", + TextInput( + title=_("Tenant ID / Directory ID"), + allow_empty=False, + size=45, + ), + ), + ( + "client", + TextInput( + title=_("Client ID / Application ID"), + allow_empty=False, + size=45, + ), + ), + ( + "secret", + IndividualOrStoredPassword( +# Password( + title=_("Client Secret"), + allow_empty=False, + size=45, + ), + ), + ( + "vaults", + ListOfStrings( + title=_("Keyvaults"), + allow_empty=False, + ), + ), + ], + ) + + +rulespec_registry.register( + CheckParameterRulespecWithItem( + check_group_name="azure_keyvault", + group=RulespecGroupCheckParametersApplications, + match_type='dict', + parameter_valuespec=_valuespec_special_agents_azure_keyvault_check, + ) +) + +rulespec_registry.register( + HostRulespec( + group=RulespecGroupCheckParametersDiscovery, + match_type='dict', + name="special_agents:azure_keyvault", + valuespec=_valuespec_special_agents_azure_keyvault_discovery, + ) +)