1,457 bytes · the Python implementation · view raw
from .monitor_cert_expiry_types import CertExpiry
def _whole(v: object) -> bool:
return isinstance(v, int) andnot 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."""ifnot _whole(not_after) ornot _whole(now):
raise ValueError("notAfter and now must be whole seconds, received %r and %r" % (not_after, now))
ifnot _whole(critical_days) or critical_days < 0:
raise ValueError("criticalDays must be a whole number 0 or more, received %r" % (critical_days,))
ifnot _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 // 86400if 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)