From 2f6011a04f1726b0e9ad9ba9648d6696dc64a09d Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Thu, 24 Mar 2022 14:14:30 -0400 Subject: [PATCH] Provide more detailed information in certificate events (#150) * Provide more detailed information in certificate events The `cert_*` events were only providing the domain. This was pretty limited, because not much can be done with it without also knowing the issuer, since that affects where the cert is stored. Providing both the `issuerKey` and `certKey` makes it possible for the event listener to call `StorageKeys.SiteCert(issuerKey, certKey)` to get the actual location of the cert (and similarly the private key). Particularly useful in situations where the user wants to copy the cert/key to some location for another app to use the cert that is being managed. A similar change could probably also be done for `cached_managed_cert` and `cached_unmanaged_cert` events to provide more detail, because `cert.Names` string slice doesn't seem that useful, can't do much with that alone. But I'm not sure I understand the usefulness of those events, so meh. Caching seems like pretty much an internal implementation detail of certmagic. * Adjust struct and field naming * Mark CertificateEventData as experimental --- config.go | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index 26260701..535abd07 100644 --- a/config.go +++ b/config.go @@ -573,7 +573,11 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool return fmt.Errorf("[%s] Obtain: saving assets: %v", name, err) } - cfg.emit("cert_obtained", name) + cfg.emit("cert_obtained", CertificateEventData{ + Name: name, + IssuerKey: issuerUsed.IssuerKey(), + StorageKey: certRes.NamesKey(), + }) if log != nil { log.Info("certificate obtained successfully", zap.String("identifier", name)) @@ -789,7 +793,11 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv return fmt.Errorf("[%s] Renew: saving assets: %v", name, err) } - cfg.emit("cert_renewed", name) + cfg.emit("cert_renewed", CertificateEventData{ + Name: name, + IssuerKey: issuerUsed.IssuerKey(), + StorageKey: certRes.NamesKey(), + }) if log != nil { log.Info("certificate renewed successfully", zap.String("identifier", name)) @@ -868,7 +876,11 @@ func (cfg *Config) RevokeCert(ctx context.Context, domain string, reason int, in return fmt.Errorf("issuer %d (%s): %v", i, issuerKey, err) } - cfg.emit("cert_revoked", domain) + cfg.emit("cert_revoked", CertificateEventData{ + Name: domain, + IssuerKey: issuerKey, + StorageKey: certRes.NamesKey(), + }) err = cfg.deleteSiteAssets(ctx, issuerKey, domain) if err != nil { @@ -1093,6 +1105,20 @@ type OCSPConfig struct { ResponderOverrides map[string]string } +// CertificateEventData contains contextual information for +// an obtained, renewed or revoked certificate. +// EXPERIMENTAL: subject to change. +type CertificateEventData struct { + // Domain or subject name of the certificate. + Name string + + // Storage key for the issuer used for this certificate. + IssuerKey string + + // Location in storage at which the certificate could be found. + StorageKey string +} + // certIssueLockOp is the name of the operation used // when naming a lock to make it mutually exclusive // with other certificate issuance operations for a