Source code for check_pa.modules.certificate

# -*- coding: utf-8 -*-

import logging

import nagiosplugin as np
from datetime import datetime

from check_pa.xml_reader import XMLReader, Finder

_log = logging.getLogger('nagiosplugin')


[docs]def get_now(): """ Extract method for mocking datetime.now. :return: datetime.today() object """ return datetime.today() # pragma: no cover
[docs]def create_check(args): """ Creates and configures a check for the certificate command. :return: the throughput check. """ return np.Check( Certificate(args.host, args.token, args.exclude), CertificateContext('certificates', args.range), CertificateSummary(args.range))
[docs]class Certificate(np.Resource): """ Will fetch the certificates from the REST API and returns a warning if the remaining days of the certificate is between the value of warning (e. g. 20) and critical (e. g. 0). If a certificate has been revoked or excluded, no warning will appear. """ def __init__(self, host, token, exclude): self.host = host self.token = token self.cmd = '<show><config><running>' \ '<xpath>shared/certificate</xpath>' \ '</running></config></show>' self.xml_obj = XMLReader(self.host, self.token, self.cmd) self.exclude = str(exclude).split(",")
[docs] def probe(self): """ Querys the REST-API and create certificate metrics. :return: a certificate metric. """ _log.info('Reading XML from: %s', self.xml_obj.build_request_url()) soup = self.xml_obj.read() certificates = soup.find_all('entry') for certificate in certificates: not_valid_after = Finder.find_item(certificate, 'not-valid-after').replace( "GMT", "").strip() date_object = datetime.strptime(not_valid_after, '%b %d %H:%M:%S %Y') difference = date_object - get_now() _log.debug('Certificate %s difference: %s days' % ( certificate.get('name'), difference.days)) try: status = Finder.find_item(certificate, 'status') except np.CheckError: status = "" if certificate.get('name') not in self.exclude: if status != "revoked": yield np.Metric(certificate.get('name'), difference.days, context='certificates')
[docs]class CertificateContext(np.Context): def __init__(self, name, r, fmt_metric='{name} expires in {valueunit}', result_cls=np.Result): super(CertificateContext, self).__init__(name, fmt_metric, result_cls) self.r = np.Range(r)
[docs] def evaluate(self, metric, resource): """Output depending on given start and end range. Returns a warning, if a certificate is between given start and end range. Returns ok, if a certificate is out of range. :param metric: :param resource: :return: """ if self.r.match(metric.value): return self.result_cls(np.Warn, None, metric) else: return self.result_cls(np.Ok, None, metric)
[docs]class CertificateSummary(np.Summary): def __init__(self, r): self.r = np.Range(r)
[docs] def ok(self, results): l = [] for result in results: l.append(result.metric.value) output = 'The next certificate will expire in %s days.' % min(l) return str(output)
[docs] def problem(self, results): l = [] for result in results: if self.r.match(result.metric.value): l.append(str(result) + ' days') output = ", ".join(l) return str(output)