Functional Weave
Code in Rust

monitor.cert-expiry@1.0.0

impl/python.py

1,457 bytes · the Python implementation · view raw

from .monitor_cert_expiry_types import CertExpiry


def _whole(v: object) -> bool:
    return isinstance(v, int) and not isinstance(v, bool)


def cert_expiry(not_after: int, now: int, warn_days: int, critical_days: int) -> CertExpiry:
    """RFC 5280 makes validity inclusive of notAfter, so a certificate is
    expired only after that second, not at it. Thresholds compare whole days
    left with the day counts: fewer than N days (secondsLeft < N * 86400) is
    exactly floor(secondsLeft / 86400) < N, with no multiplication to
    overflow."""
    if not _whole(not_after) or not _whole(now):
        raise ValueError("notAfter and now must be whole seconds, received %r and %r" % (not_after, now))
    if not _whole(critical_days) or critical_days < 0:
        raise ValueError("criticalDays must be a whole number 0 or more, received %r" % (critical_days,))
    if not _whole(warn_days) or warn_days < critical_days:
        raise ValueError("warnDays must be a whole number at least criticalDays (%d), received %r" % (critical_days, warn_days))
    if now > not_after:
        return CertExpiry(state="expired", seconds_left=0, days_left=0)
    seconds_left = not_after - now
    days_left = seconds_left // 86400
    if days_left < critical_days:
        state = "critical"
    elif days_left < warn_days:
        state = "warning"
    else:
        state = "ok"
    return CertExpiry(state=state, seconds_left=seconds_left, days_left=days_left)