Informations about renewed certificates are now passed to the renew hook (#1108)

This commit is contained in:
sdlspr 2020-04-11 14:57:06 +02:00 committed by GitHub
parent 3213540c52
commit 7a61e681b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 14 deletions

View file

@ -133,8 +133,7 @@ func (s *CertificatesStorage) ReadResource(domain string) certificate.Resource {
}
func (s *CertificatesStorage) ExistsFile(domain, extension string) bool {
filename := sanitizedDomain(domain) + extension
filePath := filepath.Join(s.rootPath, filename)
filePath := s.GetFileName(domain, extension)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
@ -145,10 +144,12 @@ func (s *CertificatesStorage) ExistsFile(domain, extension string) bool {
}
func (s *CertificatesStorage) ReadFile(domain, extension string) ([]byte, error) {
filename := sanitizedDomain(domain) + extension
filePath := filepath.Join(s.rootPath, filename)
return ioutil.ReadFile(s.GetFileName(domain, extension))
}
return ioutil.ReadFile(filePath)
func (s *CertificatesStorage) GetFileName(domain, extension string) string {
filename := sanitizedDomain(domain) + extension
return filepath.Join(s.rootPath, filename)
}
func (s *CertificatesStorage) ReadCertificate(domain, extension string) ([]*x509.Certificate, error) {

View file

@ -6,6 +6,7 @@ import (
"crypto/x509"
"errors"
"fmt"
"os"
"os/exec"
"strings"
"time"
@ -17,6 +18,13 @@ import (
"github.com/urfave/cli"
)
const (
renewEnvAccountEmail = "LEGO_ACCOUNT_EMAIL"
renewEnvCertDomain = "LEGO_CERT_DOMAIN"
renewEnvCertPath = "LEGO_CERT_PATH"
renewEnvCertKeyPath = "LEGO_CERT_KEY_PATH"
)
func createRenew() cli.Command {
return cli.Command{
Name: "renew",
@ -72,16 +80,18 @@ func renew(ctx *cli.Context) error {
bundle := !ctx.Bool("no-bundle")
meta := map[string]string{renewEnvAccountEmail: account.Email}
// CSR
if ctx.GlobalIsSet("csr") {
return renewForCSR(ctx, client, certsStorage, bundle)
return renewForCSR(ctx, client, certsStorage, bundle, meta)
}
// Domains
return renewForDomains(ctx, client, certsStorage, bundle)
return renewForDomains(ctx, client, certsStorage, bundle, meta)
}
func renewForDomains(ctx *cli.Context, client *lego.Client, certsStorage *CertificatesStorage, bundle bool) error {
func renewForDomains(ctx *cli.Context, client *lego.Client, certsStorage *CertificatesStorage, bundle bool, meta map[string]string) error {
domains := ctx.GlobalStringSlice("domains")
domain := domains[0]
@ -131,10 +141,14 @@ func renewForDomains(ctx *cli.Context, client *lego.Client, certsStorage *Certif
certsStorage.SaveResource(certRes)
return renewHook(ctx)
meta[renewEnvCertDomain] = domain
meta[renewEnvCertPath] = certsStorage.GetFileName(domain, "crt")
meta[renewEnvCertKeyPath] = certsStorage.GetFileName(domain, "key")
return renewHook(ctx, meta)
}
func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *CertificatesStorage, bundle bool) error {
func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *CertificatesStorage, bundle bool, meta map[string]string) error {
csr, err := readCSRFile(ctx.GlobalString("csr"))
if err != nil {
log.Fatal(err)
@ -167,7 +181,11 @@ func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *Certificat
certsStorage.SaveResource(certRes)
return renewHook(ctx)
meta[renewEnvCertDomain] = domain
meta[renewEnvCertPath] = certsStorage.GetFileName(domain, "crt")
meta[renewEnvCertKeyPath] = certsStorage.GetFileName(domain, "key")
return renewHook(ctx, meta)
}
func needRenewal(x509Cert *x509.Certificate, domain string, days int) bool {
@ -203,17 +221,22 @@ func merge(prevDomains []string, nextDomains []string) []string {
return prevDomains
}
func renewHook(ctx *cli.Context) error {
func renewHook(ctx *cli.Context, meta map[string]string) error {
hook := ctx.String("renew-hook")
if hook == "" {
return nil
}
ctxCmd, cancel := context.WithTimeout(context.Background(), 30*time.Second)
ctxCmd, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
parts := strings.Fields(hook)
output, err := exec.CommandContext(ctxCmd, parts[0], parts[1:]...).CombinedOutput()
cmdCtx := exec.CommandContext(ctxCmd, parts[0], parts[1:]...)
cmdCtx.Env = append(os.Environ(), metaToEnv(meta)...)
output, err := cmdCtx.CombinedOutput()
if len(output) > 0 {
fmt.Println(string(output))
}
@ -224,3 +247,13 @@ func renewHook(ctx *cli.Context) error {
return err
}
func metaToEnv(meta map[string]string) []string {
var envs []string
for k, v := range meta {
envs = append(envs, k+"="+v)
}
return envs
}

View file

@ -38,6 +38,13 @@ The hook is executed only when the certificates are effectively renewed.
lego --email="foo@bar.com" --domains="example.com" --http renew --renew-hook="./myscript.sh"
```
Some information are added to the environment variables when the hook is used:
- `LEGO_ACCOUNT_EMAIL`: the email of the account.
- `LEGO_CERT_DOMAIN`: the main domain of the certificate.
- `LEGO_CERT_PATH`: the path of the certificate.
- `LEGO_CERT_KEY_PATH`: the path of the certificate key.
### Obtain a certificate using the DNS challenge
```bash