feat: new logger (slog) (#2800)

This commit is contained in:
Ludovic Fernandez 2026-01-19 18:06:42 +01:00 committed by GitHub
commit 218ec2c138
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 325 additions and 319 deletions

View file

@ -101,9 +101,9 @@ linters:
- Print
- Printf
- Warn
- Warnf
- Fatal
- Fatalf
- LazySprintf
misspell:
locale: US
ignore-rules:
@ -280,6 +280,9 @@ linters:
text: 'SA1019: linodego\.(DomainsPagedResponse|DomainRecordsPagedResponse) is deprecated'
linters:
- staticcheck
- path: log/logger.go
linters:
- gochecknoinits
issues:
max-issues-per-linter: 0

View file

@ -99,7 +99,7 @@ func (a *Core) retrievablePost(ctx context.Context, uri string, content []byte,
}
notify := func(err error, duration time.Duration) {
log.Infof("retry due to: %v", err)
log.Warn("Retry.", "error", err)
}
return backoff.Retry(ctx, operation,

View file

@ -41,7 +41,7 @@ func (c *Certifier) getAuthorizations(ctx context.Context, order acme.ExtendedOr
}
for i, auth := range order.Authorizations {
log.Infof("[%s] AuthURL: %s", order.Identifiers[i].Value, auth)
log.Info("Authorization", "url", order.Identifiers[i].Value, "authz", auth)
}
close(resc)
@ -54,19 +54,19 @@ func (c *Certifier) deactivateAuthorizations(ctx context.Context, order acme.Ext
for _, authzURL := range order.Authorizations {
auth, err := c.core.Authorizations.Get(ctx, authzURL)
if err != nil {
log.Infof("Unable to get the authorization for %s: %v", authzURL, err)
log.Info("Unable to get the authorization.", "url", authzURL, "error", err)
continue
}
if auth.Status == acme.StatusValid && !force {
log.Infof("Skipping deactivating of valid auth: %s", authzURL)
log.Info("Skipping deactivating of valid authorization.", "url", authzURL)
continue
}
log.Infof("Deactivating auth: %s", authzURL)
log.Info("Deactivating authorization.", "url", authzURL)
if c.core.Authorizations.Deactivate(ctx, authzURL) != nil {
log.Infof("Unable to deactivate the authorization: %s", authzURL)
log.Info("Unable to deactivate the authorization.", "url", authzURL)
}
}
}

View file

@ -165,9 +165,9 @@ func (c *Certifier) Obtain(ctx context.Context, request ObtainRequest) (*Resourc
domains := sanitizeDomain(request.Domains)
if request.Bundle {
log.Infof("[%s] acme: Obtaining bundled SAN certificate", strings.Join(domains, ", "))
log.Info("acme: Obtaining bundled SAN certificate.", "domains", strings.Join(domains, ", "))
} else {
log.Infof("[%s] acme: Obtaining SAN certificate", strings.Join(domains, ", "))
log.Info("acme: Obtaining SAN certificate.", "domains", strings.Join(domains, ", "))
}
orderOpts := &api.OrderOptions{
@ -196,7 +196,7 @@ func (c *Certifier) Obtain(ctx context.Context, request ObtainRequest) (*Resourc
return nil, err
}
log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
log.Info("acme: Validations succeeded; requesting certificates.", "domains", strings.Join(domains, ", "))
failures := newObtainError()
@ -233,9 +233,9 @@ func (c *Certifier) ObtainForCSR(ctx context.Context, request ObtainForCSRReques
domains := certcrypto.ExtractDomainsCSR(request.CSR)
if request.Bundle {
log.Infof("[%s] acme: Obtaining bundled SAN certificate given a CSR", strings.Join(domains, ", "))
log.Info("acme: Obtaining bundled SAN certificate given a CSR.", "domains", strings.Join(domains, ", "))
} else {
log.Infof("[%s] acme: Obtaining SAN certificate given a CSR", strings.Join(domains, ", "))
log.Info("acme: Obtaining SAN certificate given a CSR.", "domains", strings.Join(domains, ", "))
}
orderOpts := &api.OrderOptions{
@ -264,7 +264,7 @@ func (c *Certifier) ObtainForCSR(ctx context.Context, request ObtainForCSRReques
return nil, err
}
log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
log.Info("acme: Validations succeeded; requesting certificates.", "domains", strings.Join(domains, ", "))
failures := newObtainError()
@ -414,7 +414,7 @@ func (c *Certifier) checkResponse(ctx context.Context, order acme.ExtendedOrder,
certRes.CertStableURL = order.Certificate
if preferredChain == "" {
log.Infof("[%s] Server responded with a certificate.", certRes.Domain)
log.Info("Server responded with a certificate.", "domain", certRes.Domain)
return true, nil
}
@ -426,7 +426,7 @@ func (c *Certifier) checkResponse(ctx context.Context, order acme.ExtendedOrder,
}
if ok {
log.Infof("[%s] Server responded with a certificate for the preferred certificate chains %q.", certRes.Domain, preferredChain)
log.Info("Server responded with a certificate.", "domain", certRes.Domain, "preferredChain", preferredChain)
certRes.IssuerCertificate = cert.Issuer
certRes.Certificate = cert.Cert
@ -437,7 +437,7 @@ func (c *Certifier) checkResponse(ctx context.Context, order acme.ExtendedOrder,
}
}
log.Infof("lego has been configured to prefer certificate chains with issuer %q, but no chain from the CA matched this issuer. Using the default certificate chain instead.", preferredChain)
log.Info("lego has been configured to prefer certificate chains with issuer, but no chain from the CA matched this issuer. Using the default certificate chain instead.", "preferredChain", preferredChain)
return true, nil
}
@ -529,7 +529,7 @@ func (c *Certifier) RenewWithOptions(ctx context.Context, certRes Resource, opti
// This is just meant to be informal for the user.
timeLeft := x509Cert.NotAfter.Sub(time.Now().UTC())
log.Infof("[%s] acme: Trying renewal with %d hours remaining", certRes.Domain, int(timeLeft.Hours()))
log.Info("acme: Trying renewal.", "domain", certRes.Domain, "hoursRemaining", int(timeLeft.Hours()))
// We always need to request a new certificate to renew.
// Start by checking to see if the certificate was based off a CSR,
@ -742,7 +742,7 @@ func sanitizeDomain(domains []string) []string {
for _, domain := range domains {
sanitizedDomain, err := idna.ToASCII(domain)
if err != nil {
log.Infof("skip domain %q: unable to sanitize (punnycode): %v", domain, err)
log.Warn("skip domain: unable to sanitize (punnycode).", "domain", domain, "error", err)
} else {
sanitizedDomains = append(sanitizedDomains, sanitizedDomain)
}

View file

@ -66,7 +66,7 @@ func NewChallenge(core *api.Core, validate ValidateFunc, provider challenge.Prov
for _, opt := range opts {
err := opt(chlg)
if err != nil {
log.Infof("challenge option error: %v", err)
log.Warn("Challenge option skipped.", "error", err)
}
}
@ -77,7 +77,7 @@ func NewChallenge(core *api.Core, validate ValidateFunc, provider challenge.Prov
// It does not validate record propagation, or do anything at all with the acme server.
func (c *Challenge) PreSolve(ctx context.Context, authz acme.Authorization) error {
domain := challenge.GetTargetedDomain(authz)
log.Infof("[%s] acme: Preparing to solve DNS-01", domain)
log.Info("acme: Preparing to solve DNS-01.", "domain", domain)
chlng, err := challenge.FindChallenge(challenge.DNS01, authz)
if err != nil {
@ -104,7 +104,7 @@ func (c *Challenge) PreSolve(ctx context.Context, authz acme.Authorization) erro
func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error {
domain := challenge.GetTargetedDomain(authz)
log.Infof("[%s] acme: Trying to solve DNS-01", domain)
log.Info("acme: Trying to solve DNS-01.", "domain", domain)
chlng, err := challenge.FindChallenge(challenge.DNS01, authz)
if err != nil {
@ -128,14 +128,14 @@ func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error {
timeout, interval = DefaultPropagationTimeout, DefaultPollingInterval
}
log.Infof("[%s] acme: Checking DNS record propagation. [nameservers=%s]", domain, strings.Join(recursiveNameservers, ","))
log.Info("acme: Checking DNS record propagation.", "domain", domain, "nameservers", strings.Join(recursiveNameservers, ","))
time.Sleep(interval)
err = wait.For("propagation", timeout, interval, func() (bool, error) {
stop, errP := c.preCheck.call(domain, info.EffectiveFQDN, info.Value)
if !stop || errP != nil {
log.Infof("[%s] acme: Waiting for DNS record propagation.", domain)
log.Info("acme: Waiting for DNS record propagation.", "domain", domain)
}
return stop, errP
@ -151,7 +151,7 @@ func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error {
// CleanUp cleans the challenge.
func (c *Challenge) CleanUp(authz acme.Authorization) error {
log.Infof("[%s] acme: Cleaning DNS-01 challenge", challenge.GetTargetedDomain(authz))
log.Info("acme: Cleaning DNS-01 challenge.", "domain", challenge.GetTargetedDomain(authz))
chlng, err := challenge.FindChallenge(challenge.DNS01, authz)
if err != nil {
@ -237,7 +237,7 @@ func getChallengeFQDN(domain string, followCNAME bool) string {
break
}
log.Infof("Found CNAME entry for %q: %q", fqdn, cname)
log.Info("Found CNAME entry.", "fqdn", fqdn, "cname", cname)
fqdn = cname
}

View file

@ -45,7 +45,7 @@ func NewChallenge(core *api.Core, validate ValidateFunc, provider challenge.Prov
for _, opt := range opts {
err := opt(chlg)
if err != nil {
log.Infof("challenge option error: %v", err)
log.Warn("Challenge option skipped.", "error", err)
}
}
@ -58,7 +58,7 @@ func (c *Challenge) SetProvider(provider challenge.Provider) {
func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error {
domain := challenge.GetTargetedDomain(authz)
log.Infof("[%s] acme: Trying to solve HTTP-01", domain)
log.Info("acme: Trying to solve HTTP-01.", "domain", domain)
chlng, err := challenge.FindChallenge(challenge.HTTP01, authz)
if err != nil {
@ -79,7 +79,7 @@ func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error {
defer func() {
err := c.provider.CleanUp(authz.Identifier.Value, chlng.Token, keyAuth)
if err != nil {
log.Warnf("[%s] acme: cleaning up failed: %v", domain, err)
log.Warn("acme: cleaning up failed.", "domain", domain, "error", err)
}
}()

View file

@ -120,12 +120,16 @@ func (s *ProviderServer) serve(domain, token, keyAuth string) {
return
}
log.Infof("[%s] Served key authentication", domain)
log.Info("Served key authentication.", "domain", domain)
return
}
log.Warnf("Received request for domain %s with method %s but the domain did not match any challenge. Please ensure you are passing the %s header properly.", r.Host, r.Method, s.matcher.name())
log.Warn("Received request but the domain did not match any challenge. Please ensure you are passing the header properly.",
"domain", r.Host,
"method", r.Method,
"header", s.matcher.name(),
)
_, err := w.Write([]byte("TEST"))
if err != nil {
@ -142,7 +146,7 @@ func (s *ProviderServer) serve(domain, token, keyAuth string) {
err := httpServer.Serve(s.listener)
if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
log.Println(err)
log.Warn("HTTP server serve.", "error", err)
}
s.done <- true

View file

@ -63,7 +63,7 @@ func (p *Prober) Solve(ctx context.Context, authorizations []acme.Authorization)
domain := challenge.GetTargetedDomain(authz)
if authz.Status == acme.StatusValid {
// Boulder might recycle recent validated authz (see issue #267)
log.Infof("[%s] acme: authorization already valid; skipping challenge", domain)
log.Info("acme: authorization already valid; skipping challenge.", "domain", domain)
continue
}
@ -130,7 +130,7 @@ func sequentialSolve(ctx context.Context, authSolvers []*selectedAuthSolver, fai
if len(authSolvers)-1 > i {
solvr := authSolver.solver.(sequential)
_, interval := solvr.Sequential()
log.Infof("sequence: wait for %s", interval)
log.Info("sequence: wait.", "interval", interval)
time.Sleep(interval)
}
}
@ -178,7 +178,7 @@ func cleanUp(solvr solver, authz acme.Authorization) {
err := solvr.CleanUp(authz)
if err != nil {
log.Warnf("[%s] acme: cleaning up failed: %v ", domain, err)
log.Warn("acme: cleaning up failed.", "domain", domain, "error", err)
}
}
}

View file

@ -68,11 +68,11 @@ func (c *SolverManager) chooseSolver(authz acme.Authorization) solver {
domain := challenge.GetTargetedDomain(authz)
for _, chlg := range authz.Challenges {
if solvr, ok := c.solvers[challenge.Type(chlg.Type)]; ok {
log.Infof("[%s] acme: use %s solver", domain, chlg.Type)
log.Info("acme: use solver.", "domain", domain, "type", chlg.Type)
return solvr
}
log.Infof("[%s] acme: Could not find solver for: %s", domain, chlg.Type)
log.Info("acme: Could not find the solver.", "domain", domain, "type", chlg.Type)
}
return nil
@ -90,7 +90,7 @@ func validate(ctx context.Context, core *api.Core, domain string, chlg acme.Chal
}
if valid {
log.Infof("[%s] The server validated our request", domain)
log.Info("The server validated our request.", "domain", domain)
return nil
}
@ -123,7 +123,7 @@ func validate(ctx context.Context, core *api.Core, domain string, chlg acme.Chal
}
if valid {
log.Infof("[%s] The server validated our request", domain)
log.Info("The server validated our request.", "domain", domain)
return nil
}

View file

@ -50,7 +50,7 @@ func NewChallenge(core *api.Core, validate ValidateFunc, provider challenge.Prov
for _, opt := range opts {
err := opt(chlg)
if err != nil {
log.Infof("challenge option error: %v", err)
log.Warn("Challenge option skipped.", "error", err)
}
}
@ -64,7 +64,7 @@ func (c *Challenge) SetProvider(provider challenge.Provider) {
// Solve manages the provider to validate and solve the challenge.
func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error {
domain := authz.Identifier.Value
log.Infof("[%s] acme: Trying to solve TLS-ALPN-01", challenge.GetTargetedDomain(authz))
log.Info("acme: Trying to solve TLS-ALPN-01.", "domain", challenge.GetTargetedDomain(authz))
chlng, err := challenge.FindChallenge(challenge.TLSALPN01, authz)
if err != nil {
@ -85,7 +85,7 @@ func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error {
defer func() {
err := c.provider.CleanUp(domain, chlng.Token, keyAuth)
if err != nil {
log.Warnf("[%s] acme: cleaning up failed: %v", challenge.GetTargetedDomain(authz), err)
log.Warn("acme: cleaning up failed.", "domain", challenge.GetTargetedDomain(authz), err)
}
}()

View file

@ -74,7 +74,7 @@ func (s *ProviderServer) Present(domain, token, keyAuth string) error {
go func() {
err := http.Serve(s.listener, nil)
if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
log.Println(err)
log.Warn("HTTP server serve.", "error", err)
}
}()

View file

@ -79,7 +79,7 @@ func NewAccountsStorage(ctx *cli.Context) *AccountsStorage {
serverURL, err := url.Parse(ctx.String(flgServer))
if err != nil {
log.Fatal(err)
log.Fatal("URL parsing", "flag", flgServer, "serverURL", ctx.String(flgServer), "error", err)
}
rootPath := filepath.Join(ctx.String(flgPath), baseAccountsRootFolderName)
@ -103,7 +103,7 @@ func (s *AccountsStorage) ExistsAccountFilePath() bool {
if _, err := os.Stat(accountFile); os.IsNotExist(err) {
return false
} else if err != nil {
log.Fatal(err)
log.Fatal("Could not read the account file.", "filepath", accountFile, "error", err)
}
return true
@ -137,14 +137,14 @@ func (s *AccountsStorage) Save(account *Account) error {
func (s *AccountsStorage) LoadAccount(privateKey crypto.PrivateKey) *Account {
fileBytes, err := os.ReadFile(s.accountFilePath)
if err != nil {
log.Fatalf("Could not load file for account %s: %v", s.GetUserID(), err)
log.Fatal("Could not load the account file.", "userID", s.GetUserID(), "error", err)
}
var account Account
err = json.Unmarshal(fileBytes, &account)
if err != nil {
log.Fatalf("Could not parse file for account %s: %v", s.GetUserID(), err)
log.Fatal("Could not parse the account file.", "userID", s.GetUserID(), "error", err)
}
account.key = privateKey
@ -152,14 +152,14 @@ func (s *AccountsStorage) LoadAccount(privateKey crypto.PrivateKey) *Account {
if account.Registration == nil || account.Registration.Body.Status == "" {
reg, err := tryRecoverRegistration(s.ctx, privateKey)
if err != nil {
log.Fatalf("Could not load account for %s. Registration is nil: %#v", s.GetUserID(), err)
log.Fatal("Could not load the account file. Registration is nil.", "userID", s.GetUserID(), "error", err)
}
account.Registration = reg
err = s.Save(&account)
if err != nil {
log.Fatalf("Could not save account for %s. Registration is nil: %#v", s.GetUserID(), err)
log.Fatal("Could not save the account file. Registration is nil.", "userID", s.GetUserID(), "error", err)
}
}
@ -170,22 +170,22 @@ func (s *AccountsStorage) GetPrivateKey(keyType certcrypto.KeyType) crypto.Priva
accKeyPath := filepath.Join(s.keysPath, s.GetUserID()+".key")
if _, err := os.Stat(accKeyPath); os.IsNotExist(err) {
log.Printf("No key found for account %s. Generating a %s key.", s.GetUserID(), keyType)
log.Info("No key found for the account. Generating a new private key.", "userID", s.GetUserID(), "keyType", keyType)
s.createKeysFolder()
privateKey, err := generatePrivateKey(accKeyPath, keyType)
if err != nil {
log.Fatalf("Could not generate RSA private account key for account %s: %v", s.GetUserID(), err)
log.Fatal("Could not generate the RSA private account key.", "userID", s.GetUserID(), "error", err)
}
log.Printf("Saved key to %s", accKeyPath)
log.Info("Saved key.", "filepath", accKeyPath)
return privateKey
}
privateKey, err := loadPrivateKey(accKeyPath)
if err != nil {
log.Fatalf("Could not load RSA private key from file %s: %v", accKeyPath, err)
log.Fatal("Could not load an RSA private key from the file.", "filepath", accKeyPath, "error", err)
}
return privateKey
@ -193,7 +193,7 @@ func (s *AccountsStorage) GetPrivateKey(keyType certcrypto.KeyType) crypto.Priva
func (s *AccountsStorage) createKeysFolder() {
if err := createNonExistingFolder(s.keysPath); err != nil {
log.Fatalf("Could not check/create directory for account %s: %v", s.GetUserID(), err)
log.Fatal("Could not check/create the directory for the account.", "userID", s.GetUserID(), "error", err)
}
}

View file

@ -65,7 +65,7 @@ func NewCertificatesStorage(ctx *cli.Context) *CertificatesStorage {
switch pfxFormat {
case "DES", "RC2", "SHA256":
default:
log.Fatalf("Invalid PFX format: %s", pfxFormat)
log.Fatal("Invalid PFX format.", "format", pfxFormat)
}
return &CertificatesStorage{
@ -82,14 +82,14 @@ func NewCertificatesStorage(ctx *cli.Context) *CertificatesStorage {
func (s *CertificatesStorage) CreateRootFolder() {
err := createNonExistingFolder(s.rootPath)
if err != nil {
log.Fatalf("Could not check/create path: %v", err)
log.Fatal("Could not check/create the root folder", "filepath", s.rootPath, "error", err)
}
}
func (s *CertificatesStorage) CreateArchiveFolder() {
err := createNonExistingFolder(s.archivePath)
if err != nil {
log.Fatalf("Could not check/create path: %v", err)
log.Fatal("Could not check/create the archive folder.", "filepath", s.archivePath, "error", err)
}
}
@ -104,13 +104,13 @@ func (s *CertificatesStorage) SaveResource(certRes *certificate.Resource) {
// as web servers would not be able to work with a combined file.
err := s.WriteFile(domain, certExt, certRes.Certificate)
if err != nil {
log.Fatalf("Unable to save Certificate for domain %s\n\t%v", domain, err)
log.Fatal("Unable to save Certificate.", "domain", domain, "error", err)
}
if certRes.IssuerCertificate != nil {
err = s.WriteFile(domain, issuerExt, certRes.IssuerCertificate)
if err != nil {
log.Fatalf("Unable to save IssuerCertificate for domain %s\n\t%v", domain, err)
log.Fatal("Unable to save IssuerCertificate.", "domain", domain, "error", err)
}
}
@ -118,33 +118,33 @@ func (s *CertificatesStorage) SaveResource(certRes *certificate.Resource) {
if certRes.PrivateKey != nil {
err = s.WriteCertificateFiles(domain, certRes)
if err != nil {
log.Fatalf("Unable to save PrivateKey for domain %s\n\t%v", domain, err)
log.Fatal("Unable to save PrivateKey.", "domain", domain, "error", err)
}
} else if s.pem || s.pfx {
// we don't have the private key; can't write the .pem or .pfx file
log.Fatalf("Unable to save PEM or PFX without private key for domain %s. Are you using a CSR?", domain)
log.Fatal("Unable to save PEM or PFX without the private key. Are you using a CSR?", "domain", domain)
}
jsonBytes, err := json.MarshalIndent(certRes, "", "\t")
if err != nil {
log.Fatalf("Unable to marshal CertResource for domain %s\n\t%v", domain, err)
log.Fatal("Unable to marshal CertResource.", "domain", domain, "error", err)
}
err = s.WriteFile(domain, resourceExt, jsonBytes)
if err != nil {
log.Fatalf("Unable to save CertResource for domain %s\n\t%v", domain, err)
log.Fatal("Unable to save CertResource.", "domain", domain, "error", err)
}
}
func (s *CertificatesStorage) ReadResource(domain string) certificate.Resource {
raw, err := s.ReadFile(domain, resourceExt)
if err != nil {
log.Fatalf("Error while loading the meta data for domain %s\n\t%v", domain, err)
log.Fatal("Error while loading the metadata.", "domain", domain, "error", err)
}
var resource certificate.Resource
if err = json.Unmarshal(raw, &resource); err != nil {
log.Fatalf("Error while marshaling the meta data for domain %s\n\t%v", domain, err)
log.Fatal("Error while marshaling the metadata.", "domain", domain, "error", err)
}
return resource
@ -156,7 +156,7 @@ func (s *CertificatesStorage) ExistsFile(domain, extension string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
} else if err != nil {
log.Fatal(err)
log.Fatal("File stat", "filepath", filePath, "error", err)
}
return true
@ -319,7 +319,7 @@ func getPFXEncoder(pfxFormat string) (*pkcs12.Encoder, error) {
func sanitizedDomain(domain string) string {
safe, err := idna.ToASCII(strings.NewReplacer(":", "-", "*", "_").Replace(domain))
if err != nil {
log.Fatal(err)
log.Fatal("Could not sanitize the domain.", "domain", domain, "error", err)
}
return safe

View file

@ -1,22 +1,24 @@
package cmd
import (
"fmt"
"github.com/go-acme/lego/v5/log"
"github.com/urfave/cli/v2"
)
func Before(ctx *cli.Context) error {
if ctx.String(flgPath) == "" {
log.Fatalf("Could not determine current working directory. Please pass --%s.", flgPath)
log.Fatal(fmt.Sprintf("Could not determine the current working directory. Please pass --%s.", flgPath))
}
err := createNonExistingFolder(ctx.String(flgPath))
if err != nil {
log.Fatalf("Could not check/create path: %v", err)
log.Fatal("Could not check/create the path.", "flag", flgPath, "filepath", ctx.String(flgPath), "error", err)
}
if ctx.String(flgServer) == "" {
log.Fatalf("Could not determine current working server. Please pass --%s.", flgServer)
log.Fatal(fmt.Sprintf("Could not determine the current working server. Please pass --%s.", flgServer))
}
return nil

View file

@ -4,6 +4,7 @@ import (
"crypto"
"crypto/x509"
"errors"
"fmt"
"math/rand"
"os"
"slices"
@ -42,15 +43,15 @@ func createRenew() *cli.Command {
hasCsr := ctx.String(flgCSR) != ""
if hasDomains && hasCsr {
log.Fatalf("Please specify either --%s/-d or --%s/-c, but not both", flgDomains, flgCSR)
log.Fatal(fmt.Sprintf("Please specify either --%s/-d or --%s/-c, but not both", flgDomains, flgCSR))
}
if !hasDomains && !hasCsr {
log.Fatalf("Please specify --%s/-d (or --%s/-c if you already have a CSR)", flgDomains, flgCSR)
log.Fatal(fmt.Sprintf("Please specify --%s/-d (or --%s/-c if you already have a CSR)", flgDomains, flgCSR))
}
if ctx.Bool(flgForceCertDomains) && hasCsr {
log.Fatalf("--%s only works with --%s/-d, --%s/-c doesn't support this option.", flgForceCertDomains, flgDomains, flgCSR)
log.Fatal(fmt.Sprintf("--%s only works with --%s/-d, --%s/-c doesn't support this option.", flgForceCertDomains, flgDomains, flgCSR))
}
return nil
@ -137,7 +138,7 @@ func renew(cliCtx *cli.Context) error {
account, keyType := setupAccount(cliCtx, NewAccountsStorage(cliCtx))
if account.Registration == nil {
log.Fatalf("Account %s is not registered. Use 'run' to register a new account.\n", account.Email)
log.Fatal("The account is not registered. Use 'run' to register a new account.", "email", account.Email)
}
certsStorage := NewCertificatesStorage(cliCtx)
@ -166,7 +167,7 @@ func renewForDomains(cliCtx *cli.Context, account *Account, keyType certcrypto.K
// as web servers would not be able to work with a combined file.
certificates, err := certsStorage.ReadCertificate(domain, certExt)
if err != nil {
log.Fatalf("Error while loading the certificate for domain %s\n\t%v", domain, err)
log.Fatal("Error while loading the certificate.", "domain", domain, "error", err)
}
cert := certificates[0]
@ -187,14 +188,14 @@ func renewForDomains(cliCtx *cli.Context, account *Account, keyType certcrypto.K
// Figure out if we need to sleep before renewing.
if ariRenewalTime.After(now) {
log.Infof("[%s] Sleeping %s until renewal time %s", domain, ariRenewalTime.Sub(now), ariRenewalTime)
log.Info("Sleeping until renewal time", "domain", domain, "sleep", ariRenewalTime.Sub(now), "renewalTime", ariRenewalTime)
time.Sleep(ariRenewalTime.Sub(now))
}
}
replacesCertID, err = certificate.MakeARICertID(cert)
if err != nil {
log.Fatalf("Error while construction the ARI CertID for domain %s\n\t%v", domain, err)
log.Fatal("Error while construction the ARI CertID.", "domain", domain, "error", err)
}
}
@ -213,14 +214,14 @@ func renewForDomains(cliCtx *cli.Context, account *Account, keyType certcrypto.K
// This is just meant to be informal for the user.
timeLeft := cert.NotAfter.Sub(time.Now().UTC())
log.Infof("[%s] acme: Trying renewal with %d hours remaining", domain, int(timeLeft.Hours()))
log.Info("acme: Trying renewal.", "domain", domain, "hoursRemaining", int(timeLeft.Hours()))
var privateKey crypto.PrivateKey
if cliCtx.Bool(flgReuseKey) {
keyBytes, errR := certsStorage.ReadFile(domain, keyExt)
if errR != nil {
log.Fatalf("Error while loading the private key for domain %s\n\t%v", domain, errR)
log.Fatal("Error while loading the private key.", "domain", domain, "error", errR)
}
privateKey, errR = certcrypto.ParsePEMPrivateKey(keyBytes)
@ -238,7 +239,7 @@ func renewForDomains(cliCtx *cli.Context, account *Account, keyType certcrypto.K
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
sleepTime := time.Duration(rnd.Int63n(int64(jitter)))
log.Infof("renewal: random delay of %s", sleepTime)
log.Info("renewal: random delay.", "sleep", sleepTime)
time.Sleep(sleepTime)
}
@ -265,7 +266,7 @@ func renewForDomains(cliCtx *cli.Context, account *Account, keyType certcrypto.K
certRes, err := client.Certificate.Obtain(cliCtx.Context, request)
if err != nil {
log.Fatal(err)
log.Fatal("Could not obtain the certificate.", "error", err)
}
certRes.Domain = domain
@ -280,12 +281,12 @@ func renewForDomains(cliCtx *cli.Context, account *Account, keyType certcrypto.K
func renewForCSR(cliCtx *cli.Context, account *Account, keyType certcrypto.KeyType, certsStorage *CertificatesStorage, bundle bool, meta map[string]string) error {
csr, err := readCSRFile(cliCtx.String(flgCSR))
if err != nil {
log.Fatal(err)
log.Fatal("Could not read CSR file.", "flag", flgCSR, "filepath", cliCtx.String(flgCSR), "error", err)
}
domain, err := certcrypto.GetCSRMainDomain(csr)
if err != nil {
log.Fatalf("Error: %v", err)
log.Fatal("Could not get CSR main domain.", "error", err)
}
// load the cert resource from files.
@ -293,7 +294,7 @@ func renewForCSR(cliCtx *cli.Context, account *Account, keyType certcrypto.KeyTy
// as web servers would not be able to work with a combined file.
certificates, err := certsStorage.ReadCertificate(domain, certExt)
if err != nil {
log.Fatalf("Error while loading the certificate for domain %s\n\t%v", domain, err)
log.Fatal("Error while loading the certificate.", "domain", domain, "error", err)
}
cert := certificates[0]
@ -314,14 +315,14 @@ func renewForCSR(cliCtx *cli.Context, account *Account, keyType certcrypto.KeyTy
// Figure out if we need to sleep before renewing.
if ariRenewalTime.After(now) {
log.Infof("[%s] Sleeping %s until renewal time %s", domain, ariRenewalTime.Sub(now), ariRenewalTime)
log.Info("Sleeping until renewal time", "domain", domain, "sleep", ariRenewalTime.Sub(now), "renewalTime", ariRenewalTime)
time.Sleep(ariRenewalTime.Sub(now))
}
}
replacesCertID, err = certificate.MakeARICertID(cert)
if err != nil {
log.Fatalf("Error while construction the ARI CertID for domain %s\n\t%v", domain, err)
log.Fatal("Error while construction the ARI CertID.", "domain", domain, "error", err)
}
}
@ -335,7 +336,7 @@ func renewForCSR(cliCtx *cli.Context, account *Account, keyType certcrypto.KeyTy
// This is just meant to be informal for the user.
timeLeft := cert.NotAfter.Sub(time.Now().UTC())
log.Infof("[%s] acme: Trying renewal with %d hours remaining", domain, int(timeLeft.Hours()))
log.Info("acme: Trying renewal.", "domain", domain, "hoursRemaining", int(timeLeft.Hours()))
request := certificate.ObtainForCSRRequest{
CSR: csr,
@ -353,7 +354,7 @@ func renewForCSR(cliCtx *cli.Context, account *Account, keyType certcrypto.KeyTy
certRes, err := client.Certificate.ObtainForCSR(cliCtx.Context, request)
if err != nil {
log.Fatal(err)
log.Fatal("Could not obtain the certificate fro CSR.", "error", err)
}
certsStorage.SaveResource(certRes)
@ -365,7 +366,7 @@ func renewForCSR(cliCtx *cli.Context, account *Account, keyType certcrypto.KeyTy
func needRenewal(x509Cert *x509.Certificate, domain string, days int, dynamic bool) bool {
if x509Cert.IsCA {
log.Fatalf("[%s] Certificate bundle starts with a CA certificate", domain)
log.Fatal("Certificate bundle starts with a CA certificate.", "domain", domain)
}
if dynamic {
@ -381,8 +382,8 @@ func needRenewal(x509Cert *x509.Certificate, domain string, days int, dynamic bo
return true
}
log.Printf("[%s] The certificate expires in %d days, the number of days defined to perform the renewal is %d: no renewal.",
domain, notAfter, days)
log.Infof(log.LazySprintf("Skip renewal: the certificate expires in %d days, the number of days defined to perform the renewal is %d.",
notAfter, days), "domain", domain)
return false
}
@ -401,8 +402,8 @@ func needRenewalDynamic(x509Cert *x509.Certificate, domain string, now time.Time
return true
}
log.Infof("[%s] The certificate expires at %s, the renewal can be performed in %s: no renewal.",
domain, x509Cert.NotAfter.Format(time.RFC3339), dueDate.Sub(now))
log.Infof(log.LazySprintf("Skip renewal: The certificate expires at %s, the renewal can be performed in %s.",
x509Cert.NotAfter.Format(time.RFC3339), dueDate.Sub(now)), "domain", domain)
return false
}
@ -410,18 +411,17 @@ func needRenewalDynamic(x509Cert *x509.Certificate, domain string, now time.Time
// getARIRenewalTime checks if the certificate needs to be renewed using the renewalInfo endpoint.
func getARIRenewalTime(cliCtx *cli.Context, cert *x509.Certificate, domain string, client *lego.Client) *time.Time {
if cert.IsCA {
log.Fatalf("[%s] Certificate bundle starts with a CA certificate", domain)
log.Fatal("Certificate bundle starts with a CA certificate.", "domain", domain)
}
renewalInfo, err := client.Certificate.GetRenewalInfo(cliCtx.Context, certificate.RenewalInfoRequest{Cert: cert})
if err != nil {
if errors.Is(err, api.ErrNoARI) {
// The server does not advertise a renewal info endpoint.
log.Warnf("[%s] acme: %v", domain, err)
log.Warn("acme: the server does not advertise a renewal info endpoint.", "domain", domain, "errorr", err)
return nil
}
log.Warnf("[%s] acme: calling renewal info endpoint: %v", domain, err)
log.Warn("acme: calling renewal info endpoint", "domain", domain, "error", err)
return nil
}
@ -430,14 +430,14 @@ func getARIRenewalTime(cliCtx *cli.Context, cert *x509.Certificate, domain strin
renewalTime := renewalInfo.ShouldRenewAt(now, cliCtx.Duration(flgARIWaitToRenewDuration))
if renewalTime == nil {
log.Infof("[%s] acme: renewalInfo endpoint indicates that renewal is not needed", domain)
log.Info("acme: renewalInfo endpoint indicates that renewal is not needed.", "domain", domain)
return nil
}
log.Infof("[%s] acme: renewalInfo endpoint indicates that renewal is needed", domain)
log.Info("acme: renewalInfo endpoint indicates that renewal is needed.", "domain", domain)
if renewalInfo.ExplanationURL != "" {
log.Infof("[%s] acme: renewalInfo endpoint provided an explanation: %s", domain, renewalInfo.ExplanationURL)
log.Info("acme: renewalInfo endpoint provided an explanation.", "domain", domain, "explanationURL", renewalInfo.ExplanationURL)
}
return renewalTime

View file

@ -41,7 +41,7 @@ func revoke(cliCtx *cli.Context) error {
account, keyType := setupAccount(cliCtx, NewAccountsStorage(cliCtx))
if account.Registration == nil {
log.Fatalf("Account %s is not registered. Use 'run' to register a new account.\n", account.Email)
log.Fatal("Account is not registered. Use 'run' to register a new account.", "email", account.Email)
}
client := newClient(cliCtx, account, keyType)
@ -50,21 +50,21 @@ func revoke(cliCtx *cli.Context) error {
certsStorage.CreateRootFolder()
for _, domain := range cliCtx.StringSlice(flgDomains) {
log.Printf("Trying to revoke certificate for domain %s", domain)
log.Info("Trying to revoke the certificate.", "domain", domain)
certBytes, err := certsStorage.ReadFile(domain, certExt)
if err != nil {
log.Fatalf("Error while revoking the certificate for domain %s\n\t%v", domain, err)
log.Fatal("Error while revoking the certificate.", "domain", domain, "error", err)
}
reason := cliCtx.Uint(flgReason)
err = client.Certificate.RevokeWithReason(cliCtx.Context, certBytes, &reason)
if err != nil {
log.Fatalf("Error while revoking the certificate for domain %s\n\t%v", domain, err)
log.Fatal("Error while revoking the certificate.", "domain", domain, "error", err)
}
log.Println("Certificate was revoked.")
log.Info("Certificate was revoked.", "domain", domain)
if cliCtx.Bool(flgKeep) {
return nil
@ -77,7 +77,7 @@ func revoke(cliCtx *cli.Context) error {
return err
}
log.Println("Certificate was archived for domain:", domain)
log.Info("Certificate was archived", "domain", domain)
}
return nil

View file

@ -119,12 +119,12 @@ func run(cliCtx *cli.Context) error {
if account.Registration == nil {
reg, err := register(cliCtx, client)
if err != nil {
log.Fatalf("Could not complete registration\n\t%v", err)
log.Fatal("Could not complete registration.", "error", err)
}
account.Registration = reg
if err = accountsStorage.Save(account); err != nil {
log.Fatal(err)
log.Fatal("Could not save the account file.", "error", err)
}
fmt.Printf(rootPathWarningMessage, accountsStorage.GetRootPath())
@ -137,7 +137,7 @@ func run(cliCtx *cli.Context) error {
if err != nil {
// Make sure to return a non-zero exit code if ObtainSANCertificate returned at least one error.
// Due to us not returning partial certificate we can just exit here instead of at the end.
log.Fatalf("Could not obtain certificates:\n\t%v", err)
log.Fatal("Could not obtain certificates", "error", err)
}
certsStorage.SaveResource(cert)
@ -159,14 +159,14 @@ func handleTOS(ctx *cli.Context, client *lego.Client) bool {
reader := bufio.NewReader(os.Stdin)
log.Printf("Please review the TOS at %s", client.GetToSURL())
log.Warn("Please review the TOS", "url", client.GetToSURL())
for {
fmt.Println("Do you accept the TOS? Y/n")
text, err := reader.ReadString('\n')
if err != nil {
log.Fatalf("Could not read from console: %v", err)
log.Fatal("Could not read from the console", "error", err)
}
text = strings.Trim(text, "\r\n")
@ -192,7 +192,7 @@ func register(cliCtx *cli.Context, client *lego.Client) (*registration.Resource,
hmacEncoded := cliCtx.String(flgHMAC)
if kid == "" || hmacEncoded == "" {
log.Fatalf("Requires arguments --%s and --%s.", flgKID, flgHMAC)
log.Fatal(fmt.Sprintf("Requires arguments --%s and --%s.", flgKID, flgHMAC))
}
return client.Registration.RegisterWithExternalAccountBinding(cliCtx.Context, registration.RegisterEABOptions{

View file

@ -40,6 +40,6 @@ func main() {
err = app.Run(os.Args)
if err != nil {
log.Fatal(err)
log.Fatal("Error", "error", err)
}
}

View file

@ -78,18 +78,18 @@ func newClient(ctx *cli.Context, acc registration.User, keyType certcrypto.KeyTy
retryClient.Logger = nil
if _, v := os.LookupEnv("LEGO_DEBUG_ACME_HTTP_CLIENT"); v {
retryClient.Logger = log.Logger
retryClient.Logger = log.Default()
}
config.HTTPClient = retryClient.StandardClient()
client, err := lego.NewClient(config)
if err != nil {
log.Fatalf("Could not create client: %v", err)
log.Fatal("Could not create client.", "error", err)
}
if client.GetExternalAccountRequired() && !ctx.IsSet(flgEAB) {
log.Fatalf("Server requires External Account Binding. Use --%s with --%s and --%s.", flgEAB, flgKID, flgHMAC)
log.Fatal(fmt.Sprintf("Server requires External Account Binding. Use --%s with --%s and --%s.", flgEAB, flgKID, flgHMAC))
}
return client
@ -113,7 +113,7 @@ func getKeyType(ctx *cli.Context) certcrypto.KeyType {
return certcrypto.EC384
}
log.Fatalf("Unsupported KeyType: %s", keyType)
log.Fatal("Unsupported KeyType.", "keyType", keyType)
return ""
}
@ -202,7 +202,7 @@ func checkRetry(ctx context.Context, resp *http.Response, err error) (bool, erro
}
default:
log.Warnf("retry: %v", errorDetails)
log.Warnf(log.LazySprintf("retry: %v", errorDetails))
return rt, errorDetails
}

View file

@ -21,27 +21,27 @@ import (
func setupChallenges(ctx *cli.Context, client *lego.Client) {
if !ctx.Bool(flgHTTP) && !ctx.Bool(flgTLS) && !ctx.IsSet(flgDNS) {
log.Fatalf("No challenge selected. You must specify at least one challenge: `--%s`, `--%s`, `--%s`.", flgHTTP, flgTLS, flgDNS)
log.Fatal(fmt.Sprintf("No challenge selected. You must specify at least one challenge: `--%s`, `--%s`, `--%s`.", flgHTTP, flgTLS, flgDNS))
}
if ctx.Bool(flgHTTP) {
err := client.Challenge.SetHTTP01Provider(setupHTTPProvider(ctx), http01.SetDelay(ctx.Duration(flgHTTPDelay)))
if err != nil {
log.Fatal(err)
log.Fatal("Could not set HTTP challenge provider.", "error", err)
}
}
if ctx.Bool(flgTLS) {
err := client.Challenge.SetTLSALPN01Provider(setupTLSProvider(ctx), tlsalpn01.SetDelay(ctx.Duration(flgTLSDelay)))
if err != nil {
log.Fatal(err)
log.Fatal("Could not set TLS challenge provider.", "error", err)
}
}
if ctx.IsSet(flgDNS) {
err := setupDNS(ctx, client)
if err != nil {
log.Fatal(err)
log.Fatal("Could not set DNS challenge provider.", "error", err)
}
}
}
@ -52,33 +52,39 @@ func setupHTTPProvider(ctx *cli.Context) challenge.Provider {
case ctx.IsSet(flgHTTPWebroot):
ps, err := webroot.NewHTTPProvider(ctx.String(flgHTTPWebroot))
if err != nil {
log.Fatal(err)
log.Fatal("Could not create the webroot provider.",
"flag", flgHTTPWebroot, "webRoot", ctx.String(flgHTTPWebroot), "error", err)
}
return ps
case ctx.IsSet(flgHTTPMemcachedHost):
ps, err := memcached.NewMemcachedProvider(ctx.StringSlice(flgHTTPMemcachedHost))
if err != nil {
log.Fatal(err)
log.Fatal("Could not create the memcached provider.",
"flag", flgHTTPMemcachedHost, "memcachedHosts", strings.Join(ctx.StringSlice(flgHTTPMemcachedHost), ", "), "error", err)
}
return ps
case ctx.IsSet(flgHTTPS3Bucket):
ps, err := s3.NewHTTPProvider(ctx.String(flgHTTPS3Bucket))
if err != nil {
log.Fatal(err)
log.Fatal("Could not create the S3 provider.",
"flag", flgHTTPS3Bucket, "bucket", ctx.String(flgHTTPS3Bucket), "error", err)
}
return ps
case ctx.IsSet(flgHTTPPort):
iface := ctx.String(flgHTTPPort)
if !strings.Contains(iface, ":") {
log.Fatalf("The --%s switch only accepts interface:port or :port for its argument.", flgHTTPPort)
log.Fatal(
fmt.Sprintf("The --%s switch only accepts interface:port or :port for its argument.", flgHTTPPort),
"flag", flgHTTPPort, "port", ctx.String(flgHTTPPort),
)
}
host, port, err := net.SplitHostPort(iface)
if err != nil {
log.Fatal(err)
log.Fatal("Could not split host and port.", "iface", iface, "error", err)
}
srv := http01.NewProviderServer(host, port)
@ -105,12 +111,12 @@ func setupTLSProvider(ctx *cli.Context) challenge.Provider {
case ctx.IsSet(flgTLSPort):
iface := ctx.String(flgTLSPort)
if !strings.Contains(iface, ":") {
log.Fatalf("The --%s switch only accepts interface:port or :port for its argument.", flgTLSPort)
log.Fatal(fmt.Sprintf("The --%s switch only accepts interface:port or :port for its argument.", flgTLSPort))
}
host, port, err := net.SplitHostPort(iface)
if err != nil {
log.Fatal(err)
log.Fatal("Could not split host and port.", "iface", iface, "error", err)
}
return tlsalpn01.NewProviderServer(host, port)
@ -164,7 +170,7 @@ func setupDNS(ctx *cli.Context, client *lego.Client) error {
func checkPropagationExclusiveOptions(ctx *cli.Context) error {
if ctx.IsSet(flgDNSDisableCP) {
log.Printf("The flag '%s' is deprecated use '%s' instead.", flgDNSDisableCP, flgDNSPropagationDisableANS)
log.Warnf(log.LazySprintf("The flag '%s' is deprecated use '%s' instead.", flgDNSDisableCP, flgDNSPropagationDisableANS))
}
if (isSetBool(ctx, flgDNSDisableCP) || isSetBool(ctx, flgDNSPropagationDisableANS)) && ctx.IsSet(flgDNSPropagationWait) {

51
log/lazy.go Normal file
View file

@ -0,0 +1,51 @@
package log
import (
"context"
"fmt"
"log/slog"
)
type LazyMessage struct {
msg string
args []any
}
func LazySprintf(msg string, args ...any) LazyMessage {
return LazyMessage{
msg: msg,
args: args,
}
}
func (l LazyMessage) String() string {
return fmt.Sprintf(l.msg, l.args...)
}
// Debugf calls [Logger.Debug] on the default logger.
func Debugf(msg LazyMessage, args ...any) {
logLazy(slog.LevelDebug, msg, args...)
}
// Infof calls [Logger.Info] on the default logger.
func Infof(msg LazyMessage, args ...any) {
logLazy(slog.LevelInfo, msg, args...)
}
// Warnf calls [Logger.Warn] on the default logger.
func Warnf(msg LazyMessage, args ...any) {
logLazy(slog.LevelWarn, msg, args...)
}
// Errorf calls [Logger.Error] on the default logger.
func Errorf(msg LazyMessage, args ...any) {
logLazy(slog.LevelError, msg, args...)
}
func logLazy(level slog.Level, msg LazyMessage, args ...any) {
ctx := context.Background()
if Default().Enabled(ctx, level) {
Default().Log(ctx, level, msg.String(), args...)
}
}

View file

@ -1,59 +1,48 @@
package log
import (
"log"
"log/slog"
"os"
"sync/atomic"
)
// Logger is an optional custom logger.
var Logger StdLogger = log.New(os.Stderr, "", log.LstdFlags)
var defaultLogger atomic.Pointer[slog.Logger]
// StdLogger interface for Standard Logger.
type StdLogger interface {
Fatal(args ...any)
Fatalln(args ...any)
Fatalf(format string, args ...any)
Print(args ...any)
Println(args ...any)
Printf(format string, args ...any)
func init() {
defaultLogger.Store(slog.New(slog.NewTextHandler(os.Stdout, nil)))
}
// Fatal writes a log entry.
// It uses Logger if not nil, otherwise it uses the default log.Logger.
func Fatal(args ...any) {
Logger.Fatal(args...)
// Default returns the default [Logger].
func Default() *slog.Logger { return defaultLogger.Load() }
// SetDefault makes l the default [Logger], which is used by
// the top-level functions [Info], [Debug] and so on.
func SetDefault(l *slog.Logger) {
defaultLogger.Store(l)
}
// Fatalf writes a log entry.
// It uses Logger if not nil, otherwise it uses the default log.Logger.
func Fatalf(format string, args ...any) {
Logger.Fatalf(format, args...)
// Fatal calls [Logger.Error] on the default logger and exit with code 1.
func Fatal(msg string, args ...any) {
Default().Error(msg, args...)
os.Exit(1)
}
// Print writes a log entry.
// It uses Logger if not nil, otherwise it uses the default log.Logger.
func Print(args ...any) {
Logger.Print(args...)
// Debug calls [Logger.Debug] on the default logger.
func Debug(msg string, args ...any) {
Default().Debug(msg, args...)
}
// Println writes a log entry.
// It uses Logger if not nil, otherwise it uses the default log.Logger.
func Println(args ...any) {
Logger.Println(args...)
// Info calls [Logger.Info] on the default logger.
func Info(msg string, args ...any) {
Default().Info(msg, args...)
}
// Printf writes a log entry.
// It uses Logger if not nil, otherwise it uses the default log.Logger.
func Printf(format string, args ...any) {
Logger.Printf(format, args...)
// Warn calls [Logger.Warn] on the default logger.
func Warn(msg string, args ...any) {
Default().Warn(msg, args...)
}
// Warnf writes a log entry.
func Warnf(format string, args ...any) {
Printf("[WARN] "+format, args...)
}
// Infof writes a log entry.
func Infof(format string, args ...any) {
Printf("[INFO] "+format, args...)
// Error calls [Logger.Error] on the default logger.
func Error(msg string, args ...any) {
Default().Error(msg, args...)
}

View file

@ -160,7 +160,7 @@ func GetOrFile(envVar string) string {
fileContents, err := os.ReadFile(fileVarValue)
if err != nil {
log.Printf("Failed to read the file %s (defined by env var %s): %s", fileVarValue, fileVar, err)
log.Warn("Failed to read the file.", "filepath", fileVarValue, "envVar", fileVar, "error", err)
return ""
}

View file

@ -11,7 +11,7 @@ import (
// For polls the given function 'f', once every 'interval', up to 'timeout'.
func For(msg string, timeout, interval time.Duration, f func() (bool, error)) error {
log.Infof("Wait for %s [timeout: %s, interval: %s]", msg, timeout, interval)
log.Infof(log.LazySprintf("Wait for %s.", msg), "timeout", timeout, "interval", interval)
var lastErr error

View file

@ -138,7 +138,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
}
if d.config.Debug {
log.Infof("fqdn: %s; viewID: %d; ZoneID: %d; zone: %s", info.EffectiveFQDN, viewID, parentZoneID, name)
log.Info("bluecat: debug information.", "fqdn", info.EffectiveFQDN, "viewID", viewID, "zoneID", parentZoneID, "zone", name)
}
txtRecord := internal.Entity{

View file

@ -13,7 +13,6 @@ import (
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
"github.com/go-acme/lego/v5/providers/dns/cloudflare/internal"
)
@ -185,8 +184,6 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
d.recordIDs[token] = response.ID
d.recordIDsMu.Unlock()
log.Infof("cloudflare: new record for %s, ID %s", domain, response.ID)
return nil
}
@ -217,7 +214,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
err = d.client.DeleteDNSRecord(ctx, zoneID, recordID)
if err != nil {
log.Printf("cloudflare: failed to delete TXT record: %v", err)
return fmt.Errorf("cloudflare: failed to delete TXT record: %w", err)
}
// Delete record ID from map

View file

@ -176,7 +176,7 @@ func (d *DNSProvider) waitNameservers(ctx context.Context, domain string, zone *
return fmt.Errorf("nameserver sync on %s: %w", domain, err)
}
log.Infof("[%s] Sync %d/%d complete", domain, syncProgress.Updated, syncProgress.Total)
log.Infof(log.LazySprintf("Sync %d/%d complete", syncProgress.Updated, syncProgress.Total), "domain", domain)
if !syncProgress.Complete {
return fmt.Errorf("nameserver sync on %s not complete", domain)

View file

@ -5,12 +5,12 @@ import (
"context"
"errors"
"fmt"
"log"
"net/http"
"time"
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
"github.com/go-acme/lego/v5/providers/dns/internal/clientdebug"
"github.com/nrdcg/desec"

View file

@ -4,7 +4,6 @@ package designate
import (
"errors"
"fmt"
"log"
"os"
"slices"
"sync"
@ -12,6 +11,7 @@ import (
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
@ -155,7 +155,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
if existingRecord != nil {
if slices.Contains(existingRecord.Records, info.Value) {
log.Printf("designate: the record already exists: %s", info.Value)
log.Debug("designate: the record already exists.", "value", info.Value)
return nil
}
@ -229,7 +229,7 @@ func (d *DNSProvider) createRecord(zoneID, fqdn, value string) error {
func (d *DNSProvider) updateRecord(record *recordsets.RecordSet, value string) error {
if slices.Contains(record.Records, value) {
log.Printf("skip: the record already exists: %s", value)
log.Debug("skip: the record already exists.", "value", value)
return nil
}

View file

@ -122,7 +122,7 @@ func (c *Client) doRetry(ctx context.Context, method, uri string, body []byte, r
}
notify := func(err error, duration time.Duration) {
log.Printf("client retries because of %v", err)
log.Warn("client retries.", "error", err)
}
bo := backoff.NewExponentialBackOff()

View file

@ -15,7 +15,6 @@ import (
"github.com/akamai/AkamaiOPEN-edgegrid-golang/v11/pkg/session"
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
)
@ -158,8 +157,6 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
}
if record != nil {
log.Infof("TXT record already exists. Updating target")
if containsValue(record.Target, info.Value) {
// have a record and have entry already
return nil

View file

@ -135,7 +135,7 @@ func (d *DNSProvider) run(ctx context.Context, command, domain, token, keyAuth s
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
log.Println(scanner.Text())
log.Info(scanner.Text())
}
err = cmd.Wait()

View file

@ -2,6 +2,7 @@ package exec
import (
"fmt"
"log/slog"
"os"
"strings"
"testing"
@ -13,14 +14,14 @@ import (
)
func TestDNSProvider_Present(t *testing.T) {
backupLogger := log.Logger
backupLogger := log.Default()
defer func() {
log.Logger = backupLogger
log.SetDefault(backupLogger)
}()
logRecorder := &LogRecorder{}
log.Logger = logRecorder
logHandler := &LogHandler{}
log.SetDefault(slog.New(logHandler))
type expected struct {
args string
@ -64,8 +65,8 @@ func TestDNSProvider_Present(t *testing.T) {
var message string
logRecorder.On("Println", mock.Anything).Run(func(args mock.Arguments) {
message = args.String(0)
logHandler.On("Handle", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
message = args.Get(1).(slog.Record).Message
fmt.Fprintln(os.Stdout, "XXX", message)
})
@ -88,14 +89,14 @@ func TestDNSProvider_Present(t *testing.T) {
}
func TestDNSProvider_CleanUp(t *testing.T) {
backupLogger := log.Logger
backupLogger := log.Default()
defer func() {
log.Logger = backupLogger
log.SetDefault(backupLogger)
}()
logRecorder := &LogRecorder{}
log.Logger = logRecorder
logHandler := &LogHandler{}
log.SetDefault(slog.New(logHandler))
type expected struct {
args string
@ -139,8 +140,8 @@ func TestDNSProvider_CleanUp(t *testing.T) {
var message string
logRecorder.On("Println", mock.Anything).Run(func(args mock.Arguments) {
message = args.String(0)
logHandler.On("Handle", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
message = args.Get(1).(slog.Record).Message
fmt.Fprintln(os.Stdout, "XXX", message)
})

View file

@ -1,31 +1,30 @@
package exec
import "github.com/stretchr/testify/mock"
import (
"context"
"log/slog"
type LogRecorder struct {
"github.com/stretchr/testify/mock"
)
type LogHandler struct {
mock.Mock
}
func (*LogRecorder) Fatal(args ...any) {
func (l *LogHandler) Enabled(ctx context.Context, level slog.Level) bool {
return true
}
func (l *LogHandler) Handle(ctx context.Context, record slog.Record) error {
l.Called(ctx, record)
return nil
}
func (l *LogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
panic("implement me")
}
func (*LogRecorder) Fatalln(args ...any) {
panic("implement me")
}
func (*LogRecorder) Fatalf(format string, args ...any) {
panic("implement me")
}
func (*LogRecorder) Print(args ...any) {
panic("implement me")
}
func (l *LogRecorder) Println(args ...any) {
l.Called(args...)
}
func (*LogRecorder) Printf(format string, args ...any) {
func (l *LogHandler) WithGroup(name string) slog.Handler {
panic("implement me")
}

View file

@ -96,7 +96,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
}
if config.APIKey != "" {
log.Print("gandiv5: API Key is deprecated, use Personal Access Token instead")
log.Warn("gandiv5: API Key is deprecated, use Personal Access Token instead")
}
if config.APIKey == "" && config.PersonalAccessToken == "" {

View file

@ -10,7 +10,6 @@ import (
"net/url"
"time"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/providers/dns/internal/errutils"
)
@ -99,10 +98,6 @@ func (c *Client) addTXTRecord(ctx context.Context, domain, name string, newRecor
return fmt.Errorf("unable to create TXT record for domain %s and name %s: %w", domain, name, err)
}
if message.Message != "" {
log.Infof("API response: %s", message.Message)
}
return nil
}
@ -121,10 +116,6 @@ func (c *Client) DeleteTXTRecord(ctx context.Context, domain, name string) error
return fmt.Errorf("unable to delete TXT record for domain %s and name %s: %w", domain, name, err)
}
if message.Message != "" {
log.Infof("API response: %s", message.Message)
}
return nil
}

View file

@ -212,7 +212,6 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
rrd = append(rrd, data)
if data == info.Value {
log.Printf("skip: the record already exists: %s", info.Value)
return nil
}
}
@ -257,7 +256,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
func (d *DNSProvider) applyChanges(ctx context.Context, zone string, change *gdns.Change) error {
if d.config.Debug {
data, _ := json.Marshal(change)
log.Printf("change (Create): %s", string(data))
log.Info("change (Create)", "data", string(data))
}
chg, err := d.client.Changes.Create(d.config.Project, zone, change).Do()
@ -283,7 +282,7 @@ func (d *DNSProvider) applyChanges(ctx context.Context, zone string, change *gdn
func() error {
if d.config.Debug {
data, _ := json.Marshal(change)
log.Printf("change (Get): %s", string(data))
log.Info("change (Get)", "data", string(data))
}
chg, err = d.client.Changes.Get(d.config.Project, zone, chgID).Do()

View file

@ -75,7 +75,7 @@ func NewDNSProvider() (*DNSProvider, error) {
return &DNSProvider{provider: provider}, nil
case foundAPIKey:
log.Warnf("APIKey (legacy Hetzner DNS API) is deprecated, please use APIToken (Hetzner Cloud API) instead.")
log.Warn("APIKey (legacy Hetzner DNS API) is deprecated, please use APIToken (Hetzner Cloud API) instead.")
provider, err := legacy.NewDNSProvider()
if err != nil {
@ -118,7 +118,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return &DNSProvider{provider: provider}, nil
case config.APIKey != "":
log.Warnf("%s (legacy Hetzner DNS API) is deprecated, please use %s (Hetzner Cloud API) instead.", EnvAPIKey, EnvAPIToken)
log.Warnf(log.LazySprintf("%s (legacy Hetzner DNS API) is deprecated, please use %s (Hetzner Cloud API) instead.", EnvAPIKey, EnvAPIToken))
cfg := &legacy.Config{
APIKey: config.APIKey,

View file

@ -5,13 +5,13 @@ import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/url"
"strings"
"sync"
"time"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/providers/dns/internal/errutils"
"golang.org/x/time/rate"
)
@ -108,7 +108,7 @@ func evaluateBody(body, hostname string) error {
case codeGood:
return nil
case codeNoChg:
log.Printf("%s: unchanged content written to TXT record %s", body, hostname)
log.Debug("unchanged content written to TXT record.", "hostname", hostname, "body", body)
return nil
case codeAbuse:
return fmt.Errorf("%s: blocked hostname for abuse: %s", body, hostname)

View file

@ -9,11 +9,9 @@ import (
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/providers/dns/internal/errutils"
"golang.org/x/oauth2"
)
@ -72,17 +70,9 @@ func (c *Client) DeleteDNSRecord(ctx context.Context, domainID uint64, recordID
// GetDomainByName gets a Domain object from its name.
func (c *Client) GetDomainByName(ctx context.Context, name string) (*DNSDomain, error) {
name = dns01.UnFqdn(name)
// Try to find the most specific domain
// starts with the FQDN, then remove each left label until we have a match
for {
i := strings.Index(name, ".")
if i == -1 {
break
}
domain, err := c.getDomainByName(ctx, name)
for n := range dns01.UnFqdnDomainsSeq(dns01.UnFqdn(name)) {
domain, err := c.getDomainByName(ctx, n)
if err != nil {
return nil, err
}
@ -90,10 +80,6 @@ func (c *Client) GetDomainByName(ctx context.Context, name string) (*DNSDomain,
if domain != nil {
return domain, nil
}
log.Infof("domain %q not found, trying with %q", name, name[i+1:])
name = name[i+1:]
}
return nil, fmt.Errorf("domain not found %s", name)

View file

@ -87,7 +87,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
}
if config.Sandbox {
log.Infof("inwx: sandbox mode is enabled")
log.Info("inwx: sandbox mode is enabled.")
}
client := goinwx.NewClient(config.Username, config.Password, &goinwx.ClientOptions{Sandbox: config.Sandbox})
@ -112,7 +112,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
defer func() {
errL := d.client.Account.Logout()
if errL != nil {
log.Infof("inwx: failed to log out: %v", errL)
log.Warn("inwx: failed to log out.", "error", errL)
}
}()
@ -159,7 +159,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
defer func() {
errL := d.client.Account.Logout()
if errL != nil {
log.Infof("inwx: failed to log out: %v", errL)
log.Warn("inwx: failed to log out.", "error", errL)
}
}()
@ -220,7 +220,7 @@ func (d *DNSProvider) twoFactorAuth(info *goinwx.LoginResponse) error {
// To avoid using the same TAN twice, we wait until the next TOTP period.
sleep := d.computeSleep(time.Now())
if sleep != 0 {
log.Infof("inwx: waiting %s for next TOTP token", sleep)
log.Info("inwx: waiting for the next TOTP token", "sleep", sleep)
time.Sleep(sleep)
}

View file

@ -15,7 +15,6 @@ import (
"time"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/providers/dns/internal/errutils"
)
@ -45,7 +44,6 @@ type Client struct {
token *Token
muToken sync.Mutex
Debug bool
BaseURL string
HTTPClient *http.Client
}
@ -90,10 +88,6 @@ func (c *Client) postRequest(ctx context.Context, cmd string, data url.Values) (
data.Set("auth-sid", getSessionID(ctx))
}
if c.Debug {
log.Infof("postRequest:\n\tURL: %q\n\tData: %v", endpoint, data)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, strings.NewReader(data.Encode()))
if err != nil {
return nil, fmt.Errorf("unable to create request: %w", err)

View file

@ -69,6 +69,8 @@ func (c *Client) SendRequest(ctx context.Context, zone, label, value string) err
return errutils.NewHTTPDoError(req, err)
}
defer func() { _ = resp.Body.Close() }()
raw, err := io.ReadAll(resp.Body)
if err != nil {
return errutils.NewReadResponseError(req, resp.StatusCode, err)

View file

@ -18,7 +18,6 @@ const (
EnvAPIKey = envNamespace + "API_KEY"
EnvUsername = envNamespace + "USERNAME"
EnvPassword = envNamespace + "PASSWORD"
EnvDebug = envNamespace + "DEBUG"
EnvMode = envNamespace + "API_MODE"
EnvTTL = envNamespace + "TTL"
@ -35,7 +34,6 @@ const (
// Config is used to configure the creation of the DNSProvider.
type Config struct {
Debug bool
APIKey string
Username string
Password string
@ -51,7 +49,6 @@ type Config struct {
func NewDefaultConfig() *Config {
return &Config{
APIMode: env.GetOrDefaultString(EnvMode, modeDMAPI),
Debug: env.GetOrDefaultBool(EnvDebug, false),
TTL: env.GetOrDefaultInt(EnvTTL, dns01.DefaultTTL),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),

View file

@ -8,7 +8,6 @@ import (
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
"github.com/go-acme/lego/v5/providers/dns/internal/clientdebug"
"github.com/go-acme/lego/v5/providers/dns/joker/internal/dmapi"
@ -62,8 +61,6 @@ func newDmapiProviderConfig(config *Config) (*dmapiProvider, error) {
Password: config.Password,
})
client.Debug = config.Debug
if config.HTTPClient != nil {
client.HTTPClient = config.HTTPClient
}
@ -93,13 +90,9 @@ func (d *dmapiProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err)
}
if d.config.Debug {
log.Infof("[%s] joker: adding TXT record %q to zone %q with value %q", domain, subDomain, zone, info.Value)
}
ctx, err := d.client.CreateAuthenticatedContext(context.Background())
if err != nil {
return err
return fmt.Errorf("joker: create authenticated context: %w", err)
}
response, err := d.client.GetZone(ctx, zone)
@ -131,13 +124,9 @@ func (d *dmapiProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err)
}
if d.config.Debug {
log.Infof("[%s] joker: removing entry %q from zone %q", domain, subDomain, zone)
}
ctx, err := d.client.CreateAuthenticatedContext(context.Background())
if err != nil {
return err
return fmt.Errorf("joker: create authenticated context: %w", err)
}
defer func() {

View file

@ -73,7 +73,12 @@ func (d *svcProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err)
}
return d.client.SendRequest(context.Background(), dns01.UnFqdn(zone), subDomain, info.Value)
err = d.client.SendRequest(context.Background(), dns01.UnFqdn(zone), subDomain, info.Value)
if err != nil {
return fmt.Errorf("joker: send request: %w", err)
}
return nil
}
// CleanUp removes the TXT record matching the specified parameters.
@ -90,7 +95,12 @@ func (d *svcProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err)
}
return d.client.SendRequest(context.Background(), dns01.UnFqdn(zone), subDomain, "")
err = d.client.SendRequest(context.Background(), dns01.UnFqdn(zone), subDomain, "")
if err != nil {
return fmt.Errorf("joker: send request: %w", err)
}
return nil
}
// Sequential All DNS challenges for this provider will be resolved sequentially.

View file

@ -106,7 +106,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
retryClient.HTTPClient = config.HTTPClient
}
retryClient.Logger = log.Logger
retryClient.Logger = log.Default()
client := internal.NewClient(
clientdebug.Wrap(

View file

@ -7,7 +7,7 @@ import (
"net/http"
"time"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/providers/dns/internal/clientdebug"
"github.com/go-acme/lego/v5/providers/dns/internal/errutils"
)
@ -15,11 +15,13 @@ const getIPURL = "https://dynamicdns.park-your-domain.com/getip"
// GetClientIP returns the client's public IP address.
// It uses namecheap's IP discovery service to perform the lookup.
func GetClientIP(ctx context.Context, client *http.Client, debug bool) (addr string, err error) {
func GetClientIP(ctx context.Context, client *http.Client) (addr string, err error) {
if client == nil {
client = &http.Client{Timeout: 5 * time.Second}
}
client = clientdebug.Wrap(client)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, getIPURL, http.NoBody)
if err != nil {
return "", fmt.Errorf("unable to create request: %w", err)
@ -37,9 +39,5 @@ func GetClientIP(ctx context.Context, client *http.Client, debug bool) (addr str
return "", errutils.NewReadResponseError(req, resp.StatusCode, err)
}
if debug {
log.Println("Client IP:", string(clientIP))
}
return string(clientIP), nil
}

View file

@ -39,7 +39,6 @@ const (
EnvAPIKey = envNamespace + "API_KEY"
EnvSandbox = envNamespace + "SANDBOX"
EnvDebug = envNamespace + "DEBUG"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
@ -51,7 +50,6 @@ var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
// Config is used to configure the creation of the DNSProvider.
type Config struct {
Debug bool
BaseURL string
APIUser string
APIKey string
@ -71,7 +69,6 @@ func NewDefaultConfig() *Config {
return &Config{
BaseURL: baseURL,
Debug: env.GetOrDefaultBool(EnvDebug, false),
TTL: env.GetOrDefaultInt(EnvTTL, dns01.DefaultTTL),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, time.Hour),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, 15*time.Second),
@ -115,7 +112,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
}
if config.ClientIP == "" {
clientIP, err := internal.GetClientIP(context.Background(), config.HTTPClient, config.Debug)
clientIP, err := internal.GetClientIP(context.Background(), config.HTTPClient)
if err != nil {
return nil, fmt.Errorf("namecheap: %w", err)
}
@ -166,10 +163,8 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
records = append(records, record)
if d.config.Debug {
for _, h := range records {
log.Printf("%-5.5s %-30.30s %-6s %-70.70s", h.Type, h.Name, h.TTL, h.Address)
}
for _, h := range records {
log.Debugf(log.LazySprintf("%-5.5s %-30.30s %-6s %-70.70s", h.Type, h.Name, h.TTL, h.Address))
}
err = d.client.SetHosts(ctx, pr.sld, pr.tld, records)

View file

@ -119,7 +119,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
defer func() {
err = d.client.Logout(ctx)
if err != nil {
log.Printf("netcup: %v", err)
log.Warn("netcup: failed to logout.", "error", err)
}
}()
@ -135,7 +135,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
records, err := d.client.GetDNSRecords(ctx, zone)
if err != nil {
// skip no existing records
log.Infof("no existing records, error ignored: %v", err)
log.Info("No existing records, error ignored.", "zone", zone, "error", err)
}
records = append(records, record)
@ -165,7 +165,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
defer func() {
err = d.client.Logout(ctx)
if err != nil {
log.Printf("netcup: %v", err)
log.Warn("netcup: failed to logout.", "error", err)
}
}()

View file

@ -9,7 +9,6 @@ import (
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
"github.com/go-acme/lego/v5/providers/dns/internal/clientdebug"
"gopkg.in/ns1/ns1-go.v2/rest"
@ -104,8 +103,6 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
// Create a new record
if errors.Is(err, rest.ErrRecordMissing) || record == nil {
log.Infof("Create a new record for [zone: %s, fqdn: %s, domain: %s]", zone.Zone, info.EffectiveFQDN, domain)
// Work through a bug in the NS1 API library that causes 400 Input validation failed (Value None for field '<obj>.filters' is not of type ...)
// So the `tags` and `blockedTags` parameters should be initialized to empty.
record = dns.NewRecord(zone.Zone, dns01.UnFqdn(info.EffectiveFQDN), "TXT", make(map[string]string), make([]string, 0))
@ -114,24 +111,22 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
_, err = d.client.Records.Create(record)
if err != nil {
return fmt.Errorf("ns1: failed to create record [zone: %q, fqdn: %q]: %w", zone.Zone, info.EffectiveFQDN, err)
return fmt.Errorf("ns1: create record [zone: %q, fqdn: %q]: %w", zone.Zone, info.EffectiveFQDN, err)
}
return nil
}
if err != nil {
return fmt.Errorf("ns1: failed to get the existing record: %w", err)
return fmt.Errorf("ns1: get the existing record: %w", err)
}
// Update the existing records
record.Answers = append(record.Answers, &dns.Answer{Rdata: []string{info.Value}})
log.Infof("Update an existing record for [zone: %s, fqdn: %s, domain: %s]", zone.Zone, info.EffectiveFQDN, domain)
_, err = d.client.Records.Update(record)
if err != nil {
return fmt.Errorf("ns1: failed to update record [zone: %q, fqdn: %q]: %w", zone.Zone, info.EffectiveFQDN, err)
return fmt.Errorf("ns1: update record [zone: %q, fqdn: %q]: %w", zone.Zone, info.EffectiveFQDN, err)
}
return nil
@ -150,7 +145,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
_, err = d.client.Records.Delete(zone.Zone, name, "TXT")
if err != nil {
return fmt.Errorf("ns1: failed to delete record [zone: %q, domain: %q]: %w", zone.Zone, name, err)
return fmt.Errorf("ns1: delete record [zone: %q, domain: %q]: %w", zone.Zone, name, err)
}
return nil
@ -172,7 +167,7 @@ func (d *DNSProvider) getHostedZone(fqdn string) (*dns.Zone, error) {
zone, _, err := d.client.Zones.Get(authZone, false)
if err != nil {
return nil, fmt.Errorf("failed to get zone [authZone: %q, fqdn: %q]: %w", authZone, fqdn, err)
return nil, fmt.Errorf("get zone [authZone: %q, fqdn: %q]: %w", authZone, fqdn, err)
}
return zone, nil

View file

@ -91,7 +91,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
retryClient := retryablehttp.NewClient()
retryClient.RetryMax = 5
retryClient.HTTPClient = client.HTTPClient
retryClient.Logger = log.Logger
retryClient.Logger = log.Default()
client.HTTPClient = clientdebug.Wrap(retryClient.StandardClient())

View file

@ -133,7 +133,7 @@ func getEnvFileWithStrictFallback(keys ...string) []byte {
fileContents, err := os.ReadFile(fileVarValue)
if err != nil {
log.Printf("Failed to read the file %s (defined by env var %s): %s", fileVarValue, key, err)
log.Debug("Failed to read the file.", "filepath", fileVarValue, "envVar", key, "error", err)
return nil
}

View file

@ -113,7 +113,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config.APIVersion <= 0 {
err := client.SetAPIVersion(context.Background())
if err != nil {
log.Warnf("pdns: failed to get API version %v", err)
log.Warn("pdns: failed to get API version.", "error", err)
}
}

View file

@ -10,7 +10,6 @@ import (
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
"github.com/go-acme/lego/v5/providers/dns/internal/clientdebug"
"github.com/go-acme/lego/v5/providers/dns/stackpath/internal"
@ -105,7 +104,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
zone, err := d.client.GetZones(ctx, info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("stackpath: %w", err)
return fmt.Errorf("stackpath: get zones: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, zone.Domain)
@ -120,7 +119,12 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
Data: info.Value,
}
return d.client.CreateZoneRecord(ctx, zone, record)
err = d.client.CreateZoneRecord(ctx, zone, record)
if err != nil {
return fmt.Errorf("stackpath: create zone record: %w", err)
}
return nil
}
// CleanUp removes the TXT record matching the specified parameters.
@ -131,7 +135,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
zone, err := d.client.GetZones(ctx, info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("stackpath: %w", err)
return fmt.Errorf("stackpath: get zones: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, zone.Domain)
@ -141,13 +145,13 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
records, err := d.client.GetZoneRecords(ctx, subDomain, zone)
if err != nil {
return err
return fmt.Errorf("stackpath: get zone records: %w", err)
}
for _, record := range records {
err = d.client.DeleteZoneRecord(ctx, zone, record)
if err != nil {
log.Printf("stackpath: failed to delete TXT record: %v", err)
return fmt.Errorf("stackpath: delete zone record: %w", err)
}
}

View file

@ -13,7 +13,6 @@ import (
"github.com/cenkalti/backoff/v5"
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/platform/config/env"
"github.com/go-acme/lego/v5/platform/wait"
"github.com/go-acme/lego/v5/providers/dns/internal/clientdebug"
@ -195,8 +194,6 @@ func (d *DNSProvider) waitJob(ctx context.Context, domain, id string) error {
return fmt.Errorf("apply change on %s: %w", domain, err)
}
log.Infof("variomedia: [%s] %s: %s %s", domain, result.Data.ID, result.Data.Attributes.JobType, result.Data.Attributes.Status)
if result.Data.Attributes.Status != "done" {
return fmt.Errorf("apply change on %s: status: %s", domain, result.Data.Attributes.Status)
}

View file

@ -54,7 +54,7 @@ func (r *Registrar) Register(ctx context.Context, options RegisterOptions) (*Res
}
if r.user.GetEmail() != "" {
log.Infof("acme: Registering account for %s", r.user.GetEmail())
log.Info("acme: Registering the account.", "email", r.user.GetEmail())
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
}
@ -78,7 +78,7 @@ func (r *Registrar) RegisterWithExternalAccountBinding(ctx context.Context, opti
}
if r.user.GetEmail() != "" {
log.Infof("acme: Registering account for %s", r.user.GetEmail())
log.Info("acme: Registering the account.", "email", r.user.GetEmail())
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
}
@ -104,7 +104,7 @@ func (r *Registrar) QueryRegistration(ctx context.Context) (*Resource, error) {
}
// Log the URL here instead of the email as the email may not be set
log.Infof("acme: Querying account for %s", r.user.GetRegistration().URI)
log.Info("acme: Querying the account.", "registrationURI", r.user.GetRegistration().URI)
account, err := r.core.Accounts.Get(ctx, r.user.GetRegistration().URI)
if err != nil {
@ -130,7 +130,7 @@ func (r *Registrar) UpdateRegistration(ctx context.Context, options RegisterOpti
}
if r.user.GetEmail() != "" {
log.Infof("acme: Registering account for %s", r.user.GetEmail())
log.Info("acme: Registering the account.", "email", r.user.GetEmail())
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
}
@ -150,7 +150,7 @@ func (r *Registrar) DeleteRegistration(ctx context.Context) error {
return errors.New("acme: cannot unregister a nil client or user")
}
log.Infof("acme: Deleting account for %s", r.user.GetEmail())
log.Info("acme: Deleting the account.", "email", r.user.GetEmail())
return r.core.Accounts.Deactivate(ctx, r.user.GetRegistration().URI)
}
@ -158,7 +158,7 @@ func (r *Registrar) DeleteRegistration(ctx context.Context) error {
// ResolveAccountByKey will attempt to look up an account using the given account key
// and return its registration resource.
func (r *Registrar) ResolveAccountByKey(ctx context.Context) (*Resource, error) {
log.Infof("acme: Trying to resolve account by key")
log.Info("acme: Trying to resolve the account by key")
accMsg := acme.Account{OnlyReturnExisting: true}