traefik-certs-dumper/kv.go
2019-04-19 19:10:52 +02:00

108 lines
1.9 KiB
Go

package main
import (
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io/ioutil"
"github.com/abronan/valkeyrie"
"github.com/abronan/valkeyrie/store"
"github.com/abronan/valkeyrie/store/boltdb"
"github.com/abronan/valkeyrie/store/consul"
etcdv3 "github.com/abronan/valkeyrie/store/etcd/v3"
"github.com/abronan/valkeyrie/store/zookeeper"
)
const (
storeKey = "traefik/acme/account/object"
)
func getStoredDataFromGzip(value []byte) (*StoredData, error) {
data := &StoredData{}
r, err := gzip.NewReader(bytes.NewBuffer(value))
if err != nil {
return data, err
}
acmeData, err := ioutil.ReadAll(r)
if err != nil {
return data, err
}
storedData := &StoredData{}
if err := json.Unmarshal(acmeData, &storedData); err != nil {
return data, err
}
return storedData, nil
}
// KVBackend represents a Key/Value pair backend
type KVBackend struct {
Name string
Client []string
Config *store.Config
}
func register(backend string) (store.Backend, error) {
switch backend {
case CONSUL:
consul.Register()
return store.CONSUL, nil
case ETCD:
etcdv3.Register()
return store.ETCDV3, nil
case ZK:
zookeeper.Register()
return store.ZK, nil
case BOLTDB:
boltdb.Register()
return store.BOLTDB, nil
default:
return "", fmt.Errorf("no backend found for %v", backend)
}
}
func (b KVBackend) loop(watch bool) (<-chan *StoredData, <-chan error) {
dataCh := make(chan *StoredData)
errors := make(chan error)
backend, err := register(b.Name)
if err != nil {
errors <- err
}
kvstore, err := valkeyrie.NewStore(
backend,
b.Client,
b.Config,
)
if err != nil {
errors <- err
}
go func() {
stopCh := make(<-chan struct{})
events, _ := kvstore.Watch(storeKey, stopCh, nil)
for {
kvpair := <-events
storedData, err := getStoredDataFromGzip(kvpair.Value)
if err != nil {
errors <- err
}
dataCh <- storedData
if !watch {
close(dataCh)
close(errors)
}
}
}()
return dataCh, errors
}