From 6d12a4172a13b228fbe13bb369479afbd6e39244 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 24 Nov 2016 16:46:25 +0100 Subject: [PATCH] *: enable tls support for store To enable tls the endpoints should be provided with an https scheme. Add an option to define the ca file to verify the server certificate. Add options to set the client cert and key pairs (for client authentication with etcd) Add an option to skip server tls cert verification. --- cmd/keeper/keeper.go | 19 ++++++- cmd/proxy/proxy.go | 33 ++++++++---- cmd/sentinel/sentinel.go | 20 +++++++- cmd/stolonctl/init.go | 6 +-- cmd/stolonctl/spec.go | 9 +--- cmd/stolonctl/status.go | 6 +-- cmd/stolonctl/stolonctl.go | 35 +++++++++++-- cmd/stolonctl/update.go | 7 +-- common/tls.go | 64 +++++++++++++++++++++++ pkg/store/store.go | 87 ++++++++++++++++++++++++++------ tests/integration/config_test.go | 6 +-- tests/integration/ha_test.go | 21 ++------ tests/integration/init_test.go | 32 ++---------- tests/integration/pitr_test.go | 7 +-- tests/integration/proxy_test.go | 7 +-- tests/integration/utils.go | 12 ++++- 16 files changed, 250 insertions(+), 121 deletions(-) create mode 100644 common/tls.go diff --git a/cmd/keeper/keeper.go b/cmd/keeper/keeper.go index 0d8529faf..62b2d7724 100644 --- a/cmd/keeper/keeper.go +++ b/cmd/keeper/keeper.go @@ -68,6 +68,10 @@ type config struct { id string storeBackend string storeEndpoints string + storeCertFile string + storeKeyFile string + storeCAFile string + storeSkipTlsVerify bool dataDir string clusterName string debug bool @@ -95,7 +99,11 @@ func init() { cmdKeeper.PersistentFlags().StringVar(&cfg.id, "id", "", "keeper id (must be unique in the cluster and can contain only lower-case letters, numbers and the underscore character). If not provided a random id will be generated.") cmdKeeper.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") - cmdKeeper.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") + cmdKeeper.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: http://127.0.0.1:2379 for etcd, http://127.0.0.1:8500 for consul)") + cmdKeeper.PersistentFlags().StringVar(&cfg.storeCertFile, "store-cert-file", "", "certificate file for client identification to the store") + cmdKeeper.PersistentFlags().StringVar(&cfg.storeKeyFile, "store-key", "", "private key file for client identification to the store") + cmdKeeper.PersistentFlags().StringVar(&cfg.storeCAFile, "store-ca-file", "", "verify certificates of HTTPS-enabled store servers using this CA bundle") + cmdKeeper.PersistentFlags().BoolVar(&cfg.storeSkipTlsVerify, "store-skip-tls-verify", false, "skip store certificate verification (insecure!!!)") cmdKeeper.PersistentFlags().StringVar(&cfg.dataDir, "data-dir", "", "data directory") cmdKeeper.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") cmdKeeper.PersistentFlags().StringVar(&cfg.pgListenAddress, "pg-listen-address", "localhost", "postgresql instance listening address") @@ -304,7 +312,14 @@ type PostgresKeeper struct { func NewPostgresKeeper(cfg *config, stop chan bool, end chan error) (*PostgresKeeper, error) { storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) - kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) + kvstore, err := store.NewStore(store.Config{ + Backend: store.Backend(cfg.storeBackend), + Endpoints: cfg.storeEndpoints, + CertFile: cfg.storeCertFile, + KeyFile: cfg.storeKeyFile, + CAFile: cfg.storeCAFile, + SkipTLSVerify: cfg.storeSkipTlsVerify, + }) if err != nil { return nil, fmt.Errorf("cannot create store: %v", err) } diff --git a/cmd/proxy/proxy.go b/cmd/proxy/proxy.go index 07e0f8bbd..222ffe205 100644 --- a/cmd/proxy/proxy.go +++ b/cmd/proxy/proxy.go @@ -41,20 +41,28 @@ var cmdProxy = &cobra.Command{ } type config struct { - storeBackend string - storeEndpoints string - clusterName string - listenAddress string - port string - stopListening bool - debug bool + storeBackend string + storeEndpoints string + storeCertFile string + storeKeyFile string + storeCAFile string + storeSkipTlsVerify bool + clusterName string + listenAddress string + port string + stopListening bool + debug bool } var cfg config func init() { cmdProxy.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") - cmdProxy.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") + cmdProxy.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: http://127.0.0.1:2379 for etcd, http://127.0.0.1:8500 for consul)") + cmdProxy.PersistentFlags().StringVar(&cfg.storeCertFile, "store-cert-file", "", "certificate file for client identification to the store") + cmdProxy.PersistentFlags().StringVar(&cfg.storeKeyFile, "store-key", "", "private key file for client identification to the store") + cmdProxy.PersistentFlags().StringVar(&cfg.storeCAFile, "store-ca-file", "", "verify certificates of HTTPS-enabled store servers using this CA bundle") + cmdProxy.PersistentFlags().BoolVar(&cfg.storeSkipTlsVerify, "store-skip-tls-verify", false, "skip store certificate verification (insecure!!!)") cmdProxy.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") cmdProxy.PersistentFlags().StringVar(&cfg.listenAddress, "listen-address", "127.0.0.1", "proxy listening address") cmdProxy.PersistentFlags().StringVar(&cfg.port, "port", "5432", "proxy listening port") @@ -78,7 +86,14 @@ type ClusterChecker struct { func NewClusterChecker(id string, cfg config) (*ClusterChecker, error) { storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) - kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) + kvstore, err := store.NewStore(store.Config{ + Backend: store.Backend(cfg.storeBackend), + Endpoints: cfg.storeEndpoints, + CertFile: cfg.storeCertFile, + KeyFile: cfg.storeKeyFile, + CAFile: cfg.storeCAFile, + SkipTLSVerify: cfg.storeSkipTlsVerify, + }) if err != nil { return nil, fmt.Errorf("cannot create store: %v", err) } diff --git a/cmd/sentinel/sentinel.go b/cmd/sentinel/sentinel.go index 1ffba3ce7..1afab4d1e 100644 --- a/cmd/sentinel/sentinel.go +++ b/cmd/sentinel/sentinel.go @@ -49,6 +49,10 @@ var cmdSentinel = &cobra.Command{ type config struct { storeBackend string storeEndpoints string + storeCertFile string + storeKeyFile string + storeCAFile string + storeSkipTlsVerify bool clusterName string initialClusterSpecFile string debug bool @@ -58,7 +62,11 @@ var cfg config func init() { cmdSentinel.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") - cmdSentinel.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") + cmdSentinel.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: http://127.0.0.1:2379 for etcd, http://127.0.0.1:8500 for consul)") + cmdSentinel.PersistentFlags().StringVar(&cfg.storeCertFile, "store-cert-file", "", "certificate file for client identification to the store") + cmdSentinel.PersistentFlags().StringVar(&cfg.storeKeyFile, "store-key", "", "private key file for client identification to the store") + cmdSentinel.PersistentFlags().BoolVar(&cfg.storeSkipTlsVerify, "store-skip-tls-verify", false, "skip store certificate verification (insecure!!!)") + cmdSentinel.PersistentFlags().StringVar(&cfg.storeCAFile, "store-ca-file", "", "verify certificates of HTTPS-enabled store servers using this CA bundle") cmdSentinel.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") cmdSentinel.PersistentFlags().StringVar(&cfg.initialClusterSpecFile, "initial-cluster-spec", "", "a file providing the initial cluster specification, used only at cluster initialization, ignored if cluster is already initialized") cmdSentinel.PersistentFlags().BoolVar(&cfg.debug, "debug", false, "enable debug logging") @@ -760,7 +768,15 @@ func NewSentinel(id string, cfg *config, stop chan bool, end chan bool) (*Sentin } storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) - kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) + + kvstore, err := store.NewStore(store.Config{ + Backend: store.Backend(cfg.storeBackend), + Endpoints: cfg.storeEndpoints, + CertFile: cfg.storeCertFile, + KeyFile: cfg.storeKeyFile, + CAFile: cfg.storeCAFile, + SkipTLSVerify: cfg.storeSkipTlsVerify, + }) if err != nil { return nil, fmt.Errorf("cannot create store: %v", err) } diff --git a/cmd/stolonctl/init.go b/cmd/stolonctl/init.go index af8fe55cf..e582ec18d 100644 --- a/cmd/stolonctl/init.go +++ b/cmd/stolonctl/init.go @@ -18,11 +18,9 @@ import ( "encoding/json" "io/ioutil" "os" - "path/filepath" "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - "github.com/sorintlab/stolon/pkg/store" "github.com/spf13/cobra" ) @@ -72,12 +70,10 @@ func initCluster(cmd *cobra.Command, args []string) { } } - storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) - kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) + e, err := NewStore() if err != nil { die("cannot create store: %v", err) } - e := store.NewStoreManager(kvstore, storePath) cd, _, err := e.GetClusterData() if err != nil { diff --git a/cmd/stolonctl/spec.go b/cmd/stolonctl/spec.go index e5ec6b5e2..171fcf302 100644 --- a/cmd/stolonctl/spec.go +++ b/cmd/stolonctl/spec.go @@ -16,10 +16,6 @@ package main import ( "encoding/json" - "path/filepath" - - "github.com/sorintlab/stolon/common" - "github.com/sorintlab/stolon/pkg/store" "github.com/spf13/cobra" ) @@ -35,13 +31,10 @@ func init() { } func spec(cmd *cobra.Command, args []string) { - storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) - - kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) + e, err := NewStore() if err != nil { die("cannot create store: %v", err) } - e := store.NewStoreManager(kvstore, storePath) cd, _, err := getClusterData(e) if err != nil { diff --git a/cmd/stolonctl/status.go b/cmd/stolonctl/status.go index db1e34f37..71c88ca47 100644 --- a/cmd/stolonctl/status.go +++ b/cmd/stolonctl/status.go @@ -17,13 +17,11 @@ package main import ( "fmt" "os" - "path/filepath" "sort" "text/tabwriter" "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - "github.com/sorintlab/stolon/pkg/store" "github.com/spf13/cobra" ) @@ -84,13 +82,11 @@ func status(cmd *cobra.Command, args []string) { if cfg.clusterName == "" { die("cluster name required") } - storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) - kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) + e, err := NewStore() if err != nil { die("cannot create store: %v", err) } - e := store.NewStoreManager(kvstore, storePath) sentinelsInfo, err := e.GetSentinelsInfo() if err != nil { diff --git a/cmd/stolonctl/stolonctl.go b/cmd/stolonctl/stolonctl.go index c53be6871..977596e44 100644 --- a/cmd/stolonctl/stolonctl.go +++ b/cmd/stolonctl/stolonctl.go @@ -18,8 +18,10 @@ import ( "bufio" "fmt" "os" + "path/filepath" "strings" + "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" "github.com/sorintlab/stolon/pkg/flagutil" "github.com/sorintlab/stolon/pkg/store" @@ -46,16 +48,24 @@ var cmdStolonCtl = &cobra.Command{ } type config struct { - storeBackend string - storeEndpoints string - clusterName string + storeBackend string + storeEndpoints string + storeCertFile string + storeKeyFile string + storeCAFile string + storeSkipTlsVerify bool + clusterName string } var cfg config func init() { cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") - cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") + cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: http://127.0.0.1:2379 for etcd, http://127.0.0.1:8500 for consul)") + cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeCertFile, "store-cert-file", "", "certificate file for client identification to the store") + cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeKeyFile, "store-key", "", "private key file for client identification to the store") + cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeCAFile, "store-ca-file", "", "verify certificates of HTTPS-enabled store servers using this CA bundle") + cmdStolonCtl.PersistentFlags().BoolVar(&cfg.storeSkipTlsVerify, "store-skip-tls-verify", false, "skip store certificate verification (insecure!!!)") cmdStolonCtl.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") } @@ -80,6 +90,23 @@ func die(format string, a ...interface{}) { os.Exit(1) } +func NewStore() (*store.StoreManager, error) { + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + + kvstore, err := store.NewStore(store.Config{ + Backend: store.Backend(cfg.storeBackend), + Endpoints: cfg.storeEndpoints, + CertFile: cfg.storeCertFile, + KeyFile: cfg.storeKeyFile, + CAFile: cfg.storeCAFile, + SkipTLSVerify: cfg.storeSkipTlsVerify, + }) + if err != nil { + return nil, fmt.Errorf("cannot create store: %v", err) + } + return store.NewStoreManager(kvstore, storePath), nil +} + func getClusterData(e *store.StoreManager) (*cluster.ClusterData, *kvstore.KVPair, error) { cd, pair, err := e.GetClusterData() if err != nil { diff --git a/cmd/stolonctl/update.go b/cmd/stolonctl/update.go index 39bf5823f..1bed3ddb8 100644 --- a/cmd/stolonctl/update.go +++ b/cmd/stolonctl/update.go @@ -19,11 +19,8 @@ import ( "fmt" "io/ioutil" "os" - "path/filepath" - "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - "github.com/sorintlab/stolon/pkg/store" libkvstore "github.com/docker/libkv/store" "github.com/spf13/cobra" @@ -96,12 +93,10 @@ func update(cmd *cobra.Command, args []string) { } } - storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) - kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) + e, err := NewStore() if err != nil { die("cannot create store: %v", err) } - e := store.NewStoreManager(kvstore, storePath) retry := 0 for retry < maxRetries { diff --git a/common/tls.go b/common/tls.go new file mode 100644 index 000000000..9aad31e85 --- /dev/null +++ b/common/tls.go @@ -0,0 +1,64 @@ +// Copyright 2016 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +import ( + "crypto/tls" + "crypto/x509" + "encoding/pem" + "io/ioutil" +) + +func NewTLSConfig(certFile, keyFile, caFile string, insecureSkipVerify bool) (*tls.Config, error) { + tlsConfig := tls.Config{} + + // Populate root CA certs + if caFile != "" { + pemBytes, err := ioutil.ReadFile(caFile) + if err != nil { + return nil, err + } + roots := x509.NewCertPool() + + for { + var block *pem.Block + block, pemBytes = pem.Decode(pemBytes) + if block == nil { + break + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, err + } + roots.AddCert(cert) + } + + tlsConfig.RootCAs = roots + } + + // Populate keypair + // both must be defined + if certFile != "" && keyFile != "" { + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return nil, err + } + tlsConfig.Certificates = []tls.Certificate{cert} + } + + tlsConfig.InsecureSkipVerify = insecureSkipVerify + + return &tlsConfig, nil +} diff --git a/pkg/store/store.go b/pkg/store/store.go index 195a2e93a..41d9283b2 100644 --- a/pkg/store/store.go +++ b/pkg/store/store.go @@ -15,8 +15,10 @@ package store import ( + "crypto/tls" "encoding/json" "fmt" + "net/url" "path/filepath" "strings" "time" @@ -44,6 +46,8 @@ const ( ) const ( + sentinelLeaderKey = "sentinel-leader" + keepersInfoDir = "/keepers/info/" clusterDataFile = "clusterdata" leaderSentinelInfoFile = "/sentinels/leaderinfo" @@ -52,8 +56,8 @@ const ( ) const ( - DefaultEtcdEndpoints = "127.0.0.1:2379" - DefaultConsulEndpoints = "127.0.0.1:8500" + DefaultEtcdEndpoints = "http://127.0.0.1:2379" + DefaultConsulEndpoints = "http://127.0.0.1:8500" ) const ( @@ -62,34 +66,85 @@ const ( MinTTL = 20 * time.Second ) +type Config struct { + Backend Backend + Endpoints string + CertFile string + KeyFile string + CAFile string + SkipTLSVerify bool +} + type StoreManager struct { clusterPath string store kvstore.Store } -func NewStore(backend Backend, addrsStr string) (kvstore.Store, error) { - - var kvbackend kvstore.Backend - switch backend { +func NewStore(cfg Config) (kvstore.Store, error) { + var kvBackend kvstore.Backend + switch cfg.Backend { case CONSUL: - kvbackend = kvstore.CONSUL + kvBackend = kvstore.CONSUL case ETCD: - kvbackend = kvstore.ETCD + kvBackend = kvstore.ETCD default: - return nil, fmt.Errorf("Unknown store backend: %q", backend) + return nil, fmt.Errorf("Unknown store backend: %q", cfg.Backend) } - if addrsStr == "" { - switch backend { + endpointsStr := cfg.Endpoints + if endpointsStr == "" { + switch cfg.Backend { case CONSUL: - addrsStr = DefaultConsulEndpoints + endpointsStr = DefaultConsulEndpoints case ETCD: - addrsStr = DefaultEtcdEndpoints + endpointsStr = DefaultEtcdEndpoints + } + } + endpoints := strings.Split(endpointsStr, ",") + + // 1) since libkv wants endpoints as a list of IP and not URLs but we + // want to also support them then parse and strip them + // 2) since libkv will enable TLS for all endpoints when config.TLS + // isn't nil we have to check that all the endpoints have the same + // scheme + addrs := []string{} + var scheme string + for _, e := range endpoints { + var addr string + u, err := url.Parse(e) + if err != nil { + return nil, fmt.Errorf("cannot parse endpoint %q: %v", e, err) + } + if u.Scheme == "" { + u.Scheme = "http" + addr = e + } else { + addr = u.Host } + if scheme == "" { + scheme = u.Scheme + } + if scheme != u.Scheme { + return nil, fmt.Errorf("all the endpoints must have the same scheme") + } + addrs = append(addrs, addr) + } + + var tlsConfig *tls.Config + if scheme == "https" { + var err error + tlsConfig, err = common.NewTLSConfig(cfg.CertFile, cfg.KeyFile, cfg.CAFile, cfg.SkipTLSVerify) + if err != nil { + return nil, fmt.Errorf("cannot create store tls config: %v", err) + } + } + + config := &kvstore.Config{ + TLS: tlsConfig, + ConnectionTimeout: 10 * time.Second, } - addrs := strings.Split(addrsStr, ",") - store, err := libkv.NewStore(kvbackend, addrs, &kvstore.Config{ConnectionTimeout: 10 * time.Second}) + store, err := libkv.NewStore(kvBackend, addrs, config) if err != nil { return nil, err } @@ -238,7 +293,7 @@ func (e *StoreManager) GetSentinelsInfo() (cluster.SentinelsInfo, error) { } func (e *StoreManager) GetLeaderSentinelId() (string, error) { - pair, err := e.store.Get(filepath.Join(e.clusterPath, common.SentinelLeaderKey)) + pair, err := e.store.Get(filepath.Join(e.clusterPath, sentinelLeaderKey)) if err != nil { if err != kvstore.ErrKeyNotFound { return "", err diff --git a/tests/integration/config_test.go b/tests/integration/config_test.go index f2aa986d5..5320b73bf 100644 --- a/tests/integration/config_test.go +++ b/tests/integration/config_test.go @@ -55,11 +55,7 @@ func TestServerParameters(t *testing.T) { storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, diff --git a/tests/integration/ha_test.go b/tests/integration/ha_test.go index 2b3504157..faafd3c32 100644 --- a/tests/integration/ha_test.go +++ b/tests/integration/ha_test.go @@ -70,12 +70,7 @@ func TestInitWithMultipleKeepers(t *testing.T) { storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, @@ -133,12 +128,7 @@ func setupServers(t *testing.T, clusterName, dir string, numKeepers, numSentinel storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, @@ -393,14 +383,9 @@ func testFailoverFailed(t *testing.T, syncRepl bool) { tks, tss, tstore := setupServers(t, clusterName, dir, 2, 1, syncRepl, false) defer shutdown(tks, tss, tstore) - storeEndpoints := fmt.Sprintf("%s:%s", tstore.listenAddress, tstore.port) storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) master, standbys, err := getRoles(t, tks) if err != nil { diff --git a/tests/integration/init_test.go b/tests/integration/init_test.go index 860c7675a..7971d690a 100644 --- a/tests/integration/init_test.go +++ b/tests/integration/init_test.go @@ -105,11 +105,7 @@ func testInitNew(t *testing.T, merge bool) { storeEndpoints := fmt.Sprintf("%s:%s", tstore.listenAddress, tstore.port) storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, @@ -184,11 +180,7 @@ func testInitExisting(t *testing.T, merge bool) { storeEndpoints := fmt.Sprintf("%s:%s", tstore.listenAddress, tstore.port) storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, @@ -333,11 +325,7 @@ func TestInitUsers(t *testing.T) { clusterName = uuid.NewV4().String() storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, @@ -379,12 +367,7 @@ func TestInitUsers(t *testing.T) { clusterName = uuid.NewV4().String() storePath = filepath.Join(common.StoreBasePath, clusterName) - kvstore, err = store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - - e = store.NewStoreManager(kvstore, storePath) + e = store.NewStoreManager(tstore.store, storePath) ts2, err := NewTestSentinel(t, dir, clusterName, tstore.storeBackend, storeEndpoints, fmt.Sprintf("--initial-cluster-spec=%s", initialClusterSpecFile)) if err != nil { @@ -432,12 +415,7 @@ func TestInitialClusterSpec(t *testing.T) { storeEndpoints := fmt.Sprintf("%s:%s", tstore.listenAddress, tstore.port) storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, diff --git a/tests/integration/pitr_test.go b/tests/integration/pitr_test.go index 21726a1af..5752fbe35 100644 --- a/tests/integration/pitr_test.go +++ b/tests/integration/pitr_test.go @@ -56,12 +56,7 @@ func TestPITR(t *testing.T) { storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) initialClusterSpec := &cluster.ClusterSpec{ InitMode: cluster.ClusterInitModeNew, diff --git a/tests/integration/proxy_test.go b/tests/integration/proxy_test.go index 428e86de0..691cf2e97 100644 --- a/tests/integration/proxy_test.go +++ b/tests/integration/proxy_test.go @@ -77,12 +77,7 @@ func TestProxyListening(t *testing.T) { storePath := filepath.Join(common.StoreBasePath, clusterName) - kvstore, err := store.NewStore(tstore.storeBackend, storeEndpoints) - if err != nil { - t.Fatalf("cannot create store: %v", err) - } - - e := store.NewStoreManager(kvstore, storePath) + e := store.NewStoreManager(tstore.store, storePath) cd := &cluster.ClusterData{ FormatVersion: cluster.CurrentCDFormatVersion, diff --git a/tests/integration/utils.go b/tests/integration/utils.go index b291e5cde..7159ec90f 100644 --- a/tests/integration/utils.go +++ b/tests/integration/utils.go @@ -543,7 +543,11 @@ func NewTestEtcd(t *testing.T, dir string, a ...string) (*TestStore, error) { storeEndpoints := fmt.Sprintf("%s:%s", listenAddress, port) - kvstore, err := store.NewStore(store.ETCD, storeEndpoints) + storeConfig := store.Config{ + Backend: store.ETCD, + Endpoints: storeEndpoints, + } + kvstore, err := store.NewStore(storeConfig) if err != nil { return nil, fmt.Errorf("cannot create store: %v", err) } @@ -625,7 +629,11 @@ func NewTestConsul(t *testing.T, dir string, a ...string) (*TestStore, error) { storeEndpoints := fmt.Sprintf("%s:%s", listenAddress, portHTTP) - kvstore, err := store.NewStore(store.CONSUL, storeEndpoints) + storeConfig := store.Config{ + Backend: store.CONSUL, + Endpoints: storeEndpoints, + } + kvstore, err := store.NewStore(storeConfig) if err != nil { return nil, fmt.Errorf("cannot create store: %v", err) }