2019-06-04 22:58:42 +02:00

100 lines
2.2 KiB
Go

package kv
import (
"bytes"
"compress/gzip"
"encoding/json"
"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"
// Dump Dumps KV content to certificates.
func Dump(config *Config, baseConfig *dumper.BaseConfig) error {
kvStore, err := valkeyrie.NewStore(config.Backend, config.Endpoints, config.Options)
if err != nil {
return fmt.Errorf("unable to create client of the store: %v", err)
}
storeKey := config.Prefix + storeKeySuffix
if baseConfig.Watch {
return watch(kvStore, storeKey, baseConfig)
}
pair, err := kvStore.Get(storeKey, nil)
if err != nil {
return fmt.Errorf("unable to retrieve %s value: %v", storeKey, err)
}
return dumpPair(pair, baseConfig)
}
func watch(kvStore store.Store, storeKey string, baseConfig *dumper.BaseConfig) error {
stopCh := make(<-chan struct{})
pairs, err := kvStore.Watch(storeKey, stopCh, nil)
if err != nil {
return err
}
for {
pair := <-pairs
if pair == nil {
return fmt.Errorf("could not fetch Key/Value pair for key %v", storeKey)
}
err = dumpPair(pair, baseConfig)
if err != nil {
return err
}
if isDebug() {
log.Println("Dumped new certificate data.")
}
hook.Exec(baseConfig.Hook)
}
}
func dumpPair(pair *store.KVPair, baseConfig *dumper.BaseConfig) error {
data, err := getStoredDataFromGzip(pair)
if err != nil {
return err
}
return dumper.Dump(data, baseConfig)
}
func getStoredDataFromGzip(pair *store.KVPair) (*dumper.StoredData, error) {
reader, err := gzip.NewReader(bytes.NewBuffer(pair.Value))
if err != nil {
return nil, fmt.Errorf("fail to create GZip reader: %v", err)
}
acmeData, err := ioutil.ReadAll(reader)
if err != nil {
return nil, fmt.Errorf("unable to read the pair content: %v", err)
}
account := &AccountV1{}
if err := json.Unmarshal(acmeData, &account); err != nil {
return nil, fmt.Errorf("unable marshal AccountV1: %v", err)
}
return convertAccountV1ToV2(account), nil
}
func isDebug() bool {
return strings.EqualFold(os.Getenv("TCD_DEBUG"), "true")
}