feat: adds a post hook.

This commit is contained in:
Fernandez Ludovic 2019-04-25 23:58:25 +02:00
parent 1001ead866
commit ace6229872
14 changed files with 124 additions and 53 deletions

View File

@ -61,6 +61,7 @@ func init() {
rootCmd.PersistentFlags().Bool("domain-subdir", false, "Use domain as sub-directory.")
rootCmd.PersistentFlags().Bool("clean", true, "Clean destination folder before dumping content.")
rootCmd.PersistentFlags().Bool("watch", false, "Enable watching changes.")
rootCmd.PersistentFlags().String("post-hook", "", "Execute a command only if changes occurs on the data source. (works only with the watch mode)")
}
// initConfig reads in config file and ENV variables if set.
@ -174,5 +175,6 @@ func getBaseConfig(cmd *cobra.Command) (*dumper.BaseConfig, error) {
DomainSubDir: subDir,
Clean: clean,
Watch: watch,
Hook: cmd.Flag("post-hook").Value.String(),
}, nil
}

View File

@ -9,16 +9,17 @@ Dump Let's Encrypt certificates from Traefik.
### Options
```
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
-h, --help help for traefik-certs-dumper
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--watch Enable watching changes.
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
-h, --help help for traefik-certs-dumper
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--watch Enable watching changes.
```
### SEE ALSO
@ -27,4 +28,4 @@ Dump Let's Encrypt certificates from Traefik.
* [traefik-certs-dumper kv](traefik-certs-dumper_kv.md) - Dump the content of a KV store.
* [traefik-certs-dumper version](traefik-certs-dumper_version.md) - Display version
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -20,19 +20,20 @@ traefik-certs-dumper file [flags]
### Options inherited from parent commands
```
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--watch Enable watching changes.
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--watch Enable watching changes.
```
### SEE ALSO
* [traefik-certs-dumper](traefik-certs-dumper.md) - Dump Let's Encrypt certificates from Traefik.
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -26,15 +26,16 @@ Dump the content of a KV store.
### Options inherited from parent commands
```
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--watch Enable watching changes.
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--watch Enable watching changes.
```
### SEE ALSO
@ -45,4 +46,4 @@ Dump the content of a KV store.
* [traefik-certs-dumper kv etcd](traefik-certs-dumper_kv_etcd.md) - Dump the content of etcd.
* [traefik-certs-dumper kv zookeeper](traefik-certs-dumper_kv_zookeeper.md) - Dump the content of zookeeper.
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -32,6 +32,7 @@ traefik-certs-dumper kv boltdb [flags]
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--password string Password for connection.
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--prefix string Prefix used for KV store. (default "traefik")
--tls Enable TLS encryption.
--tls.ca string Root CA for certificate verification if TLS is enabled
@ -47,4 +48,4 @@ traefik-certs-dumper kv boltdb [flags]
* [traefik-certs-dumper kv](traefik-certs-dumper_kv.md) - Dump the content of a KV store.
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -31,6 +31,7 @@ traefik-certs-dumper kv consul [flags]
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--password string Password for connection.
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--prefix string Prefix used for KV store. (default "traefik")
--tls Enable TLS encryption.
--tls.ca string Root CA for certificate verification if TLS is enabled
@ -46,4 +47,4 @@ traefik-certs-dumper kv consul [flags]
* [traefik-certs-dumper kv](traefik-certs-dumper_kv.md) - Dump the content of a KV store.
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -31,6 +31,7 @@ traefik-certs-dumper kv etcd [flags]
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--password string Password for connection.
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--prefix string Prefix used for KV store. (default "traefik")
--tls Enable TLS encryption.
--tls.ca string Root CA for certificate verification if TLS is enabled
@ -46,4 +47,4 @@ traefik-certs-dumper kv etcd [flags]
* [traefik-certs-dumper kv](traefik-certs-dumper_kv.md) - Dump the content of a KV store.
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -30,6 +30,7 @@ traefik-certs-dumper kv zookeeper [flags]
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--password string Password for connection.
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--prefix string Prefix used for KV store. (default "traefik")
--tls Enable TLS encryption.
--tls.ca string Root CA for certificate verification if TLS is enabled
@ -45,4 +46,4 @@ traefik-certs-dumper kv zookeeper [flags]
* [traefik-certs-dumper kv](traefik-certs-dumper_kv.md) - Dump the content of a KV store.
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -19,19 +19,20 @@ traefik-certs-dumper version [flags]
### Options inherited from parent commands
```
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--watch Enable watching changes.
--clean Clean destination folder before dumping content. (default true)
--config string config file (default is $HOME/.traefik-certs-dumper.yaml)
--crt-ext string The file extension of the generated certificates. (default ".crt")
--crt-name string The file name (without extension) of the generated certificates. (default "certificate")
--dest string Path to store the dump content. (default "./dump")
--domain-subdir Use domain as sub-directory.
--key-ext string The file extension of the generated private keys. (default ".key")
--key-name string The file name (without extension) of the generated private keys. (default "privatekey")
--post-hook string Execute a command only if changes occurs on the data source. (works only with the watch mode)
--watch Enable watching changes.
```
### SEE ALSO
* [traefik-certs-dumper](traefik-certs-dumper.md) - Dump Let's Encrypt certificates from Traefik.
###### Auto generated by spf13/cobra on 22-Apr-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

View File

@ -8,4 +8,5 @@ type BaseConfig struct {
DomainSubDir bool
Clean bool
Watch bool
Hook string
}

View File

@ -11,6 +11,7 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/ldez/traefik-certs-dumper/v2/dumper"
"github.com/ldez/traefik-certs-dumper/v2/hook"
)
// Dump Dumps "acme.json" file to certificates.
@ -68,7 +69,7 @@ func watch(acmeFile string, baseConfig *dumper.BaseConfig) error {
return
}
if strings.EqualFold(os.Getenv("TCD_DEBUG"), "true") {
if isDebug() {
log.Println("event:", event)
}
@ -115,7 +116,7 @@ func manageEvent(watcher *fsnotify.Watcher, event fsnotify.Event, acmeFile strin
}
if !bytes.Equal(previousHash, hash) {
if strings.EqualFold(os.Getenv("TCD_DEBUG"), "true") {
if isDebug() {
log.Println("detected changes on file:", event.Name)
}
@ -123,7 +124,11 @@ func manageEvent(watcher *fsnotify.Watcher, event fsnotify.Event, acmeFile strin
return nil, errD
}
log.Println("Dumped new certificate data.")
if isDebug() {
log.Println("Dumped new certificate data.")
}
hook.Exec(baseConfig.Hook)
}
return hash, nil
@ -156,3 +161,7 @@ func calculateHash(acmeFile string) ([]byte, error) {
return h.Sum(nil), nil
}
func isDebug() bool {
return strings.EqualFold(os.Getenv("TCD_DEBUG"), "true")
}

View File

@ -7,10 +7,13 @@ import (
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"github.com/abronan/valkeyrie"
"github.com/abronan/valkeyrie/store"
"github.com/ldez/traefik-certs-dumper/v2/dumper"
"github.com/ldez/traefik-certs-dumper/v2/hook"
)
const storeKeySuffix = "/acme/account/object"
@ -55,7 +58,11 @@ func watch(kvStore store.Store, storeKey string, baseConfig *dumper.BaseConfig)
return err
}
log.Println("Dumped new certificate data.")
if isDebug() {
log.Println("Dumped new certificate data.")
}
hook.Exec(baseConfig.Hook)
}
}
@ -86,3 +93,7 @@ func getStoredDataFromGzip(pair *store.KVPair) (*dumper.StoredData, error) {
return convertAccountV1ToV2(account), nil
}
func isDebug() bool {
return strings.EqualFold(os.Getenv("TCD_DEBUG"), "true")
}

41
hook/hook.go Normal file
View File

@ -0,0 +1,41 @@
package hook
import (
"context"
"errors"
"fmt"
"os/exec"
"strings"
"time"
)
// Exec Execute a command on a go routine.
func Exec(command string) {
if command == "" {
return
}
go func() {
errH := execute(command)
if errH != nil {
panic(errH)
}
}()
}
func execute(command string) error {
ctxCmd, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
parts := strings.Fields(command)
output, err := exec.CommandContext(ctxCmd, parts[0], parts[1:]...).CombinedOutput()
if len(output) > 0 {
fmt.Println(string(output))
}
if ctxCmd.Err() == context.DeadlineExceeded {
return errors.New("hook timed out")
}
return err
}

View File

@ -18,6 +18,7 @@
- Output formats:
- use domain as sub-directory (allow custom names and extensions)
- flat (domain as filename)
- Hook (only with watch mode and if the data source changes)
## Installation
@ -71,7 +72,6 @@ dump
└──private
├──my.domain.com.crt
└──letsencrypt.key
```
### Change source and destination
@ -84,7 +84,6 @@ test
└──private
├──my.domain.com.crt
└──letsencrypt.key
```
### Use domain as sub-directory
@ -102,7 +101,7 @@ dump
#### Change file extension
```console
$ traefik-certs-dumper file --domain-subdir=true --crt-ext=.pem --key-ext=.pem
$ traefik-certs-dumper file --domain-subdir --crt-ext=.pem --key-ext=.pem
dump
├──my.domain.com
│ ├──certificate.pem
@ -114,7 +113,7 @@ dump
#### Change file name
```console
$ traefik-certs-dumper file --domain-subdir=true --crt-name=fullchain --key-name=privkey
$ traefik-certs-dumper file --domain-subdir --crt-name=fullchain --key-name=privkey
dump
├──my.domain.com
│ ├──fullchain.crt