-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add performance data metrics to track upcoming expirations and total certificate types (scopes) in the chain: - `expires_leaf` - `expires_intermediate` - `certs_present_leaf` - `certs_present_intermediate` - `certs_present_root` - `certs_present_unknown` As part of providing these performance data metrics various helper functions were added: - `certs.NumLeafCerts` - `certs.NumIntermediateCerts` - `certs.NumRootCerts` - `certs.NumUnknownCerts` - `certs.LeafCerts` - `certs.IntermediateCerts` - `certs.RootCerts` - `certs.OldestLeafCert` - `certs.OldestIntermediateCert` - `certs.OldestRootCert` - `certs.ExpiresInDays` The README file has been updated to list the purpose of each performance data metric. As of this commit, failure to collect performance data is emitted as an error message and recorded in the plugin's error collection (for display in `LongServiceOutput`). Future work is scheduled to revisit this choice and audit exit states as a whole to determine if more appropriate exit states should be used. refs GH-445 refs GH-464
- Loading branch information
Showing
4 changed files
with
338 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// Copyright 2023 Adam Chalkley | ||
// | ||
// https://github.com/atc0005/check-cert | ||
// | ||
// Licensed under the MIT License. See LICENSE file in the project root for | ||
// full license information. | ||
|
||
package main | ||
|
||
import ( | ||
"crypto/x509" | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/atc0005/check-cert/internal/certs" | ||
"github.com/atc0005/go-nagios" | ||
) | ||
|
||
// getPerfData generates performance data metrics from the given certificate | ||
// chain and certificate age thresholds. An error is returned if any are | ||
// encountered while gathering metrics or if an empty certificate chain is | ||
// provided. | ||
func getPerfData(certChain []*x509.Certificate, ageCritical int, ageWarning int) ([]nagios.PerformanceData, error) { | ||
if len(certChain) == 0 { | ||
return nil, fmt.Errorf( | ||
"func getPerfData: unable to generate metrics: %w", | ||
certs.ErrMissingValue, | ||
) | ||
} | ||
|
||
var expiresLeaf int | ||
oldestLeaf := certs.OldestLeafCert(certChain) | ||
if daysToExpiration, err := certs.ExpiresInDays(oldestLeaf); err == nil { | ||
expiresLeaf = daysToExpiration | ||
} | ||
|
||
var expiresIntermediate int | ||
oldestIntermediate := certs.OldestIntermediateCert(certChain) | ||
if daysToExpiration, err := certs.ExpiresInDays(oldestIntermediate); err == nil { | ||
expiresIntermediate = daysToExpiration | ||
} | ||
|
||
var expiresRoot int | ||
oldestRoot := certs.OldestRootCert(certChain) | ||
if daysToExpiration, err := certs.ExpiresInDays(oldestRoot); err == nil { | ||
expiresRoot = daysToExpiration | ||
} | ||
|
||
// TODO: Should we emit this metric? | ||
_ = expiresRoot | ||
|
||
certsPresentLeaf := strconv.Itoa(certs.NumLeafCerts(certChain)) | ||
certsPresentIntermediate := strconv.Itoa(certs.NumIntermediateCerts(certChain)) | ||
certsPresentRoot := strconv.Itoa(certs.NumRootCerts(certChain)) | ||
certsPresentUnknown := strconv.Itoa(certs.NumUnknownCerts(certChain)) | ||
|
||
pd := []nagios.PerformanceData{ | ||
{ | ||
Label: "expires_leaf", | ||
Value: fmt.Sprintf("%d", expiresLeaf), | ||
UnitOfMeasurement: "d", | ||
Warn: fmt.Sprintf("%d", ageWarning), | ||
Crit: fmt.Sprintf("%d", ageCritical), | ||
}, | ||
{ | ||
Label: "expires_intermediate", | ||
Value: fmt.Sprintf("%d", expiresIntermediate), | ||
UnitOfMeasurement: "d", | ||
Warn: fmt.Sprintf("%d", ageWarning), | ||
Crit: fmt.Sprintf("%d", ageCritical), | ||
}, | ||
|
||
// TODO: Should we even track this? If we report 0 as a default value | ||
// when the cert is not found, how will that differ from when the cert | ||
// is actually present and expired? | ||
// | ||
// | ||
// NOTE: Current thinking is that I should not include root cert | ||
// expiration perfdata; root cert should ideally not be in the chain | ||
// per current best practice(s). | ||
// { | ||
// Label: "expires_root", | ||
// Value: fmt.Sprintf("%d", expiresRoot), | ||
// UnitOfMeasurement: "d", | ||
// }, | ||
{ | ||
Label: "certs_present_leaf", | ||
Value: certsPresentLeaf, | ||
}, | ||
{ | ||
Label: "certs_present_intermediate", | ||
Value: certsPresentIntermediate, | ||
}, | ||
{ | ||
Label: "certs_present_root", | ||
Value: certsPresentRoot, | ||
}, | ||
{ | ||
Label: "certs_present_unknown", | ||
Value: certsPresentUnknown, | ||
}, | ||
} | ||
|
||
return pd, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters