etcd: add support for namespaces

This commit adds support for etcd namespaces. This is useful when
using a shared etcd database where separate users have access to
separate namespaces.
This commit is contained in:
Andras Banki-Horvath 2020-12-16 18:23:06 +01:00
parent f9641cdc64
commit 4a6af67241
No known key found for this signature in database
GPG Key ID: 80E5375C094198D8
5 changed files with 28 additions and 4 deletions

View File

@ -44,6 +44,8 @@ type EtcdConfig struct {
Pass string `long:"pass" description:"Password for the database user."`
Namespace string `long:"namespace" description:"The etcd namespace to use."`
CertFile string `long:"cert_file" description:"Path to the TLS certificate for etcd RPC."`
KeyFile string `long:"key_file" description:"Path to the TLS private key for etcd RPC."`

View File

@ -12,6 +12,7 @@ import (
"github.com/btcsuite/btcwallet/walletdb"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3/namespace"
"github.com/coreos/etcd/pkg/transport"
)
@ -153,6 +154,9 @@ type BackendConfig struct {
// name spaces.
Prefix string
// Namespace is the etcd namespace that we'll use for all keys.
Namespace string
// CollectCommitStats indicates wheter to commit commit stats.
CollectCommitStats bool
}
@ -184,11 +188,15 @@ func newEtcdBackend(config BackendConfig) (*db, error) {
TLS: tlsConfig,
MaxCallSendMsgSize: 16384*1024 - 1,
})
if err != nil {
return nil, err
}
// Apply the namespace.
cli.KV = namespace.NewKV(cli.KV, config.Namespace)
cli.Watcher = namespace.NewWatcher(cli.Watcher, config.Namespace)
cli.Lease = namespace.NewLease(cli.Lease, config.Namespace)
backend := &db{
cli: cli,
config: config,

View File

@ -21,6 +21,12 @@ const (
// embedded etcd servers. Ports are monotonically increasing starting
// from this number and are determined by the results of getFreePort().
defaultEtcdPort = 2379
// defaultNamespace is the namespace we'll use in our embedded etcd
// instance. Since it is only used for testing, we'll use the namespace
// name "test/" for this. Note that the namespace can be any string,
// the trailing / is not required.
defaultNamespace = "test/"
)
var (
@ -90,6 +96,7 @@ func NewEmbeddedEtcdInstance(path string) (*BackendConfig, func(), error) {
User: "user",
Pass: "pass",
InsecureSkipVerify: true,
Namespace: defaultNamespace,
}
return connConfig, func() {

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3/namespace"
)
const (
@ -59,6 +60,11 @@ func NewEtcdTestFixture(t *testing.T) *EtcdTestFixture {
t.Fatalf("unable to create etcd test fixture: %v", err)
}
// Apply the default namespace (since that's what we use in tests).
cli.KV = namespace.NewKV(cli.KV, defaultNamespace)
cli.Watcher = namespace.NewWatcher(cli.Watcher, defaultNamespace)
cli.Lease = namespace.NewLease(cli.Lease, defaultNamespace)
return &EtcdTestFixture{
t: t,
cli: cli,
@ -88,7 +94,7 @@ func (f *EtcdTestFixture) Get(key string) string {
resp, err := f.cli.Get(ctx, key)
if err != nil {
f.t.Fatalf("etcd test fixture failed to put: %v", err)
f.t.Fatalf("etcd test fixture failed to get: %v", err)
}
if len(resp.Kvs) > 0 {
@ -103,9 +109,9 @@ func (f *EtcdTestFixture) Dump() map[string]string {
ctx, cancel := context.WithTimeout(context.TODO(), testEtcdTimeout)
defer cancel()
resp, err := f.cli.Get(ctx, "", clientv3.WithPrefix())
resp, err := f.cli.Get(ctx, "\x00", clientv3.WithFromKey())
if err != nil {
f.t.Fatalf("etcd test fixture failed to put: %v", err)
f.t.Fatalf("etcd test fixture failed to get: %v", err)
}
result := make(map[string]string)

View File

@ -28,6 +28,7 @@ func GetEtcdBackend(ctx context.Context, prefix string,
KeyFile: etcdConfig.KeyFile,
InsecureSkipVerify: etcdConfig.InsecureSkipVerify,
Prefix: prefix,
Namespace: etcdConfig.Namespace,
CollectCommitStats: etcdConfig.CollectStats,
}