Пример #1
0
// TestMultiplePersistConnection tests the second connection to a
// BoltDB fails when one is already open with PersistConnection flag
func TestMultiplePersistConnection(t *testing.T) {
	kv, err := libkv.NewStore(
		store.BOLTDB,
		[]string{"/tmp/not_exist_dir/__boltdbtest"},
		&store.Config{
			Bucket:            "boltDBTest",
			ConnectionTimeout: 1 * time.Second,
			PersistConnection: true},
	)
	assert.NoError(t, err)
	assert.NotNil(t, kv)

	if _, ok := kv.(*BoltDB); !ok {
		t.Fatal("Error registering and initializing boltDB")
	}

	// Must fail if multiple boltdb requests are made with a valid timeout
	kv, err = libkv.NewStore(
		store.BOLTDB,
		[]string{"/tmp/not_exist_dir/__boltdbtest"},
		&store.Config{
			Bucket:            "boltDBTest",
			ConnectionTimeout: 1 * time.Second,
			PersistConnection: true},
	)
	assert.Error(t, err)

	_ = os.Remove("/tmp/not_exist_dir/__boltdbtest")
}
Пример #2
0
// TestConcurrentConnection tests simultaenous get/put using
// two handles.
func TestConcurrentConnection(t *testing.T) {
	var err error
	kv1, err1 := libkv.NewStore(
		store.BOLTDB,
		[]string{"/tmp/__boltdbtest"},
		&store.Config{
			Bucket:            "boltDBTest",
			ConnectionTimeout: 1 * time.Second},
	)
	assert.NoError(t, err1)
	assert.NotNil(t, kv1)

	kv2, err2 := libkv.NewStore(
		store.BOLTDB,
		[]string{"/tmp/__boltdbtest"},
		&store.Config{Bucket: "boltDBTest",
			ConnectionTimeout: 1 * time.Second},
	)
	assert.NoError(t, err2)
	assert.NotNil(t, kv2)

	key1 := "TestKV1"
	value1 := []byte("TestVal1")
	err = kv1.Put(key1, value1, nil)
	assert.NoError(t, err)

	key2 := "TestKV2"
	value2 := []byte("TestVal2")
	err = kv2.Put(key2, value2, nil)
	assert.NoError(t, err)

	pair1, err1 := kv1.Get(key1)
	assert.NoError(t, err)
	if assert.NotNil(t, pair1) {
		assert.NotNil(t, pair1.Value)
	}
	assert.Equal(t, pair1.Value, value1)

	pair2, err2 := kv2.Get(key2)
	assert.NoError(t, err)
	if assert.NotNil(t, pair2) {
		assert.NotNil(t, pair2.Value)
	}
	assert.Equal(t, pair2.Value, value2)

	// AtomicPut using kv1 and kv2 should succeed
	_, _, err = kv1.AtomicPut(key1, []byte("TestnewVal1"), pair1, nil)
	assert.NoError(t, err)

	_, _, err = kv2.AtomicPut(key2, []byte("TestnewVal2"), pair2, nil)
	assert.NoError(t, err)

	testutils.RunTestCommon(t, kv1)
	testutils.RunTestCommon(t, kv2)

	kv1.Close()
	kv2.Close()

	_ = os.Remove("/tmp/__boltdbtest")
}
Пример #3
0
func NewStore(machines []string, cmd *ServerCommand, keyspace string) *Storage {
	etcd.Register()

	clt, err := libkv.NewStore(store.ETCD, cmd.Config.BackendMachines, &store.Config{})
	if err != nil {
		panic(err)
	}

	_, err = clt.List(keyspace)
	if err != store.ErrKeyNotFound && err != nil {
		log.WithError(err).Fatal("store: Store backend not reachable")
	}

	cfg := client.Config{
		Endpoints: machines,
		Transport: client.DefaultTransport,
		// set timeout per request to fail fast when the target endpoint is unavailable
		HeaderTimeoutPerRequest: time.Second,
	}
	c, err := client.New(cfg)
	if err != nil {
		log.Fatal(err)
	}
	kapi := client.NewKeysAPI(c)

	return &Storage{Client: clt, Kapi: kapi, command: cmd, keyspace: keyspace}
}
Пример #4
0
func (s *EtcdSuite) SetUpTest(c *check.C) {
	s.createComposeProject(c, "etcd")
	s.composeProject.Start(c)

	etcd.Register()
	url := s.composeProject.Container(c, "etcd").NetworkSettings.IPAddress + ":2379"
	kv, err := libkv.NewStore(
		store.ETCD,
		[]string{url},
		&store.Config{
			ConnectionTimeout: 10 * time.Second,
		},
	)
	if err != nil {
		c.Fatal("Cannot create store etcd")
	}
	s.kv = kv

	// wait for etcd
	err = utils.Try(60*time.Second, func() error {
		_, err := kv.Exists("test")
		if err != nil {
			return fmt.Errorf("Etcd connection error to %s: %v", url, err)
		}
		return nil
	})
	c.Assert(err, checker.IsNil)
}
Пример #5
0
func NewStore(backend string, machines []string, a *AgentCommand, keyspace string) *Store {
	store, err := libkv.NewStore(store.Backend(backend), machines, nil)
	if err != nil {
		log.Fatal(err)
	}
	return &Store{Client: store, agent: a, keyspace: keyspace}
}
Пример #6
0
func getKVStore(addr string, options *kvstore.Config) (kvstore.Store, error) {
	u, err := url.Parse(addr)
	if err != nil {
		return nil, err

	}

	kvType := strings.ToLower(u.Scheme)
	kvHost := u.Host
	var backend kvstore.Backend

	switch kvType {
	case "consul":
		backend = kvstore.CONSUL
	case "etcd":
		backend = kvstore.ETCD
	}

	kv, err := libkv.NewStore(
		backend,
		[]string{kvHost},
		options,
	)

	if err != nil {
		return nil, err

	}

	return kv, nil
}
Пример #7
0
// Initialize is exported
func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Duration) error {
	var (
		parts  = strings.SplitN(uris, "/", 2)
		addrs  = strings.Split(parts[0], ",")
		prefix = ""
		err    error
	)

	// A custom prefix to the path can be optionally used.
	if len(parts) == 2 {
		prefix = parts[1]
	}

	s.heartbeat = heartbeat
	s.ttl = ttl
	s.path = path.Join(prefix, discoveryPath)

	// Creates a new store, will ignore options given
	// if not supported by the chosen store
	s.store, err = libkv.NewStore(
		s.backend,
		addrs,
		&store.Config{
			EphemeralTTL: s.ttl,
		},
	)

	return err
}
Пример #8
0
func (s *ConsulSuite) setupConsul(c *check.C) {
	s.createComposeProject(c, "consul")
	s.composeProject.Start(c)

	consul.Register()
	kv, err := libkv.NewStore(
		store.CONSUL,
		[]string{s.composeProject.Container(c, "consul").NetworkSettings.IPAddress + ":8500"},
		&store.Config{
			ConnectionTimeout: 10 * time.Second,
		},
	)
	if err != nil {
		c.Fatal("Cannot create store consul")
	}
	s.kv = kv

	// wait for consul
	err = utils.Try(60*time.Second, func() error {
		_, err := kv.Exists("test")
		if err != nil {
			return err
		}
		return nil
	})
	c.Assert(err, checker.IsNil)
}
func NewBgpRouteManager(masterIface string, server net.IP, as string) *BgpRouteManager {
	b := &BgpRouteManager{
		ethIface:     masterIface,
		server:       server,
		neighborlist: map[string]string{},
		asnum:        as,
	}
	consul.Register()
	client := "localhost:8500"
	kv, err := libkv.NewStore(
		store.CONSUL, // or "consul"
		[]string{client},
		&store.Config{
			ConnectionTimeout: 10 * time.Second,
		},
	)
	b.kv = kv
	if err != nil {
		log.Fatal("Cannot create store consul")
	}
	b.neighborkey = "bgpneighbor"
	if exist, _ := kv.Exists(b.neighborkey); exist == false {
		err := b.kv.Put(b.neighborkey, []byte("bgpneighbor"), &store.WriteOptions{IsDir: true})
		if err != nil {
			fmt.Errorf("Something went wrong when initializing key %v", b.neighborkey)
		}
	}
	err = b.kv.Put(b.neighborkey+"/"+server.String(), []byte(as), nil)
	if err != nil {
		log.Errorf("Error trying to put value at key: %v", b.neighborkey)
	}

	return b
}
Пример #10
0
func NewStore(backend Backend, addrsStr string) (kvstore.Store, error) {

	var kvbackend kvstore.Backend
	switch backend {
	case CONSUL:
		kvbackend = kvstore.CONSUL
	case ETCD:
		kvbackend = kvstore.ETCD
	default:
		return nil, fmt.Errorf("Unknown store backend: %q", backend)
	}

	if addrsStr == "" {
		switch backend {
		case CONSUL:
			addrsStr = DefaultConsulEndpoints
		case ETCD:
			addrsStr = DefaultEtcdEndpoints
		}
	}
	addrs := strings.Split(addrsStr, ",")

	store, err := libkv.NewStore(kvbackend, addrs, &kvstore.Config{ConnectionTimeout: 10 * time.Second})
	if err != nil {
		return nil, err
	}
	return store, nil
}
Пример #11
0
// newClient used to connect to KV Store
func newClient(kv string, addrs string) (DataStore, error) {
	store, err := libkv.NewStore(store.Backend(kv), []string{addrs}, &store.Config{})
	if err != nil {
		return nil, err
	}
	ds := &datastore{store: store}
	return ds, nil
}
Пример #12
0
func NewStore(storeUrl string) (store.Store, error) {
	kv, addrs := parseStoreUrl(storeUrl)
	config := &store.Config{}

	st, err := libkv.NewStore(store.Backend(kv), addrs, config)
	if err != nil {
		return nil, err
	}

	return st, nil
}
Пример #13
0
func (provider *Kv) provide(configurationChan chan<- types.ConfigMessage) error {
	storeConfig := &store.Config{
		ConnectionTimeout: 30 * time.Second,
		Bucket:            "traefik",
	}

	if provider.TLS != nil {
		caPool := x509.NewCertPool()

		if provider.TLS.CA != "" {
			ca, err := ioutil.ReadFile(provider.TLS.CA)

			if err != nil {
				return fmt.Errorf("Failed to read CA. %s", err)
			}

			caPool.AppendCertsFromPEM(ca)
		}

		cert, err := tls.LoadX509KeyPair(provider.TLS.Cert, provider.TLS.Key)

		if err != nil {
			return fmt.Errorf("Failed to load keypair. %s", err)
		}

		storeConfig.TLS = &tls.Config{
			Certificates:       []tls.Certificate{cert},
			RootCAs:            caPool,
			InsecureSkipVerify: provider.TLS.InsecureSkipVerify,
		}
	}

	kv, err := libkv.NewStore(
		provider.storeType,
		strings.Split(provider.Endpoint, ","),
		storeConfig,
	)
	if err != nil {
		return err
	}
	if _, err := kv.List(""); err != nil {
		return err
	}
	provider.kvclient = kv
	if provider.Watch {
		go provider.watchKv(configurationChan, provider.Prefix)
	}
	configuration := provider.loadConfig()
	configurationChan <- types.ConfigMessage{
		ProviderName:  string(provider.storeType),
		Configuration: configuration,
	}
	return nil
}
Пример #14
0
func TestRegister(t *testing.T) {
	Register()

	kv, err := libkv.NewStore(store.ETCD, []string{client}, nil)
	assert.NoError(t, err)
	assert.NotNil(t, kv)

	if _, ok := kv.(*Etcd); !ok {
		t.Fatal("Error registering and initializing etcd")
	}
}
Пример #15
0
func TestRegister(t *testing.T) {
	Register()

	kv, err := libkv.NewStore(store.CONSUL, []string{client}, nil)
	assert.NoError(t, err)
	assert.NotNil(t, kv)

	if _, ok := kv.(*Consul); !ok {
		t.Fatal("Error registering and initializing consul")
	}
}
Пример #16
0
// Initialize is exported
func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Duration, clusterOpts map[string]string) error {
	var (
		parts = strings.SplitN(uris, "/", 2)
		addrs = strings.Split(parts[0], ",")
		err   error
	)

	// A custom prefix to the path can be optionally used.
	if len(parts) == 2 {
		s.prefix = parts[1]
	}

	s.heartbeat = heartbeat
	s.ttl = ttl

	// Use a custom path if specified in discovery options
	dpath := defaultDiscoveryPath
	if clusterOpts["kv.path"] != "" {
		dpath = clusterOpts["kv.path"]
	}

	s.path = path.Join(s.prefix, dpath)

	var config *store.Config
	if clusterOpts["kv.cacertfile"] != "" && clusterOpts["kv.certfile"] != "" && clusterOpts["kv.keyfile"] != "" {
		logrus.Info("Initializing discovery with TLS")
		tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
			CAFile:   clusterOpts["kv.cacertfile"],
			CertFile: clusterOpts["kv.certfile"],
			KeyFile:  clusterOpts["kv.keyfile"],
		})
		if err != nil {
			return err
		}
		config = &store.Config{
			// Set ClientTLS to trigger https (bug in libkv/etcd)
			ClientTLS: &store.ClientTLSConfig{
				CACertFile: clusterOpts["kv.cacertfile"],
				CertFile:   clusterOpts["kv.certfile"],
				KeyFile:    clusterOpts["kv.keyfile"],
			},
			// The actual TLS config that will be used
			TLS: tlsConfig,
		}
	} else {
		logrus.Info("Initializing discovery without TLS")
	}

	// Creates a new store, will ignore options given
	// if not supported by the chosen store
	s.store, err = libkv.NewStore(s.backend, addrs, config)
	return err
}
Пример #17
0
func (kvc *KVClient) prepareClient() error {
	hasCA := kvc.certificateAuthority != ""
	hasCert := kvc.clientCertificate != ""
	hasKey := kvc.clientKey != ""

	config := &store.Config{
		ConnectionTimeout: 5 * time.Second,
	}
	if hasCA || hasCert || hasKey {

		var cacert *x509.CertPool
		if kvc.certificateAuthority != "" {
			capem, err := ioutil.ReadFile(kvc.certificateAuthority)
			if err != nil {
				return err
			}
			cacert = x509.NewCertPool()
			if !cacert.AppendCertsFromPEM(capem) {
				return errors.New("unable to load certificate authority")
			}
		}

		var cert tls.Certificate
		if kvc.clientCertificate != "" && kvc.clientKey != "" {
			c := kvc.clientCertificate
			k := kvc.clientKey
			var err error
			cert, err = tls.LoadX509KeyPair(c, k)
			if err != nil {
				return err
			}
		}

		config.ClientTLS = &store.ClientTLSConfig{
			CertFile:   kvc.clientCertificate,
			KeyFile:    kvc.clientKey,
			CACertFile: kvc.certificateAuthority,
		}
		config.TLS = &tls.Config{
			RootCAs:      cacert,
			Certificates: []tls.Certificate{cert},
		}

	}
	store, err := libkv.NewStore(kvc.backend, kvc.addresses, config)
	if err != nil {
		fmt.Println(err)
		logrus.Error("unable to create kvclient. ", err)
		return err
	}
	kvc.store = store
	return nil
}
Пример #18
0
func New(config *config.BalancerConfig) (Store, error) {
	u, err := url.Parse(config.StoreAddress)
	if err != nil {
		return nil, errors.Wrap(err, "error paring store address")
	}

	scheme := u.Scheme
	if scheme != "consul" && scheme != "etcd" {
		return nil, ErrUnsupportedStore
	}

	//Validating open connection
	_, err = net.Dial("tcp", u.Host)
	if err != nil {
		return nil, errors.Wrap(err, "Store connection failed. Make sure your store is up and running.")
	}

	kv, err := libkv.NewStore(
		kv.Backend(scheme),
		[]string{u.Host},
		nil,
	)
	if err != nil {
		kv.Close()
		return nil, errors.Wrap(err, "Cannot create store consul")
	}

	svcsChs := []chan []types.Service{}
	dstsChs := []chan []types.Destination{}
	checksChs := []chan []types.CheckSpec{}

	validate := validator.New()
	// Registering custom validations
	validate.RegisterValidation("protocols", validateValues(types.Protocols))
	validate.RegisterValidation("schedulers", validateValues(types.Schedulers))

	fusisStore := &FusisStore{
		kv:                  kv,
		prefix:              config.StorePrefix,
		validate:            validate,
		servicesChannels:    svcsChs,
		destinationChannels: dstsChs,
		checksChannels:      checksChs,
	}

	go fusisStore.WatchServices()
	go fusisStore.WatchDestinations()
	go fusisStore.WatchChecks()

	return fusisStore, nil
}
Пример #19
0
// New creates a new GDStore
func New() *GDStore {
	//TODO: Make this configurable
	address := "localhost:8500"

	log.WithFields(log.Fields{"type": "consul", "consul.config": address}).Debug("Creating new store")
	s, err := libkv.NewStore(store.CONSUL, []string{address}, &store.Config{ConnectionTimeout: 10 * time.Second})
	if err != nil {
		log.WithField("error", err).Fatal("Failed to create store")
	}

	log.Info("Created new store using Consul")

	return &GDStore{s}
}
Пример #20
0
func (provider *KvProvider) provide(configurationChan chan<- configMessage) error {
	switch provider.StoreType {
	case store.CONSUL:
		consul.Register()
	case store.ETCD:
		etcd.Register()
	case store.ZK:
		zookeeper.Register()
	case store.BOLTDB:
		boltdb.Register()
	default:
		return errors.New("Invalid kv store: " + string(provider.StoreType))
	}
	kv, err := libkv.NewStore(
		provider.StoreType,
		[]string{provider.Endpoint},
		&store.Config{
			ConnectionTimeout: 30 * time.Second,
			Bucket:            "traefik",
		},
	)
	if err != nil {
		return err
	}
	if _, err := kv.List(""); err != nil {
		return err
	}
	provider.kvclient = kv
	if provider.Watch {
		stopCh := make(chan struct{})
		chanKeys, err := kv.WatchTree(provider.Prefix, stopCh)
		if err != nil {
			return err
		}
		go func() {
			for {
				<-chanKeys
				configuration := provider.loadConfig()
				if configuration != nil {
					configurationChan <- configMessage{string(provider.StoreType), configuration}
				}
				defer close(stopCh)
			}
		}()
	}
	configuration := provider.loadConfig()
	configurationChan <- configMessage{string(provider.StoreType), configuration}
	return nil
}
Пример #21
0
func New(hosts []string, config *store.Config) (store.Store, error) {
	boltdb.Register()

	s, err := libkv.NewStore(
		store.BOLTDB,
		hosts,
		config,
	)
	if err != nil {
		return nil, err
	}
	return &BoltdbStorage{
		GeneralStorage: general.New(s, string(store.BOLTDB)),
	}, nil
}
Пример #22
0
func New(hosts []string, config *store.Config) (store.Store, error) {
	consul.Register()

	s, err := libkv.NewStore(
		store.CONSUL,
		hosts,
		config,
	)
	if err != nil {
		return nil, err
	}
	return &ConsulStorage{
		GeneralStorage: general.New(s, string(store.CONSUL)),
	}, nil
}
Пример #23
0
func New(hosts []string, config *store.Config) (store.Store, error) {
	zookeeper.Register()

	s, err := libkv.NewStore(
		store.ZK,
		hosts,
		config,
	)
	if err != nil {
		return nil, err
	}
	return &ZookeeperStorage{
		GeneralStorage: general.New(s, string(store.ZK)),
	}, nil
}
Пример #24
0
func New(hosts []string, config *store.Config) (store.Store, error) {
	etcd.Register()

	s, err := libkv.NewStore(
		store.ETCD,
		hosts,
		config,
	)
	if err != nil {
		return nil, err
	}
	return &EtcdStorage{
		GeneralStorage: general.New(s, string(store.ETCD)),
	}, nil
}
Пример #25
0
func buildClient(connectionString string) (store.Store, error) {

	kv, err := libkv.NewStore(
		getBackend(connectionString),
		getAddrs(connectionString),
		&store.Config{
			ConnectionTimeout: 10 * time.Second,
		},
	)
	if err != nil {
		return nil, err
	}

	return kv, nil
}
Пример #26
0
func initializeKVStore(c *cli.Context) {
	var kvt store.Backend
	switch c.GlobalString("kvtype") {
	case "consul":
		kvt = store.CONSUL
	case "etcd":
		kvt = store.ETCD
	case "zk":
		kvt = store.ZK
	}
	k, err := libkv.NewStore(kvt, c.GlobalStringSlice("kvurl"), &store.Config{})
	if err != nil {
		logger.Fatal(err)
	}
	kvStore = k
}
Пример #27
0
func TestRegister(t *testing.T) {
	Register()

	kv, err := libkv.NewStore(
		store.BOLTDB,
		[]string{"/tmp/not_exist_dir/__boltdbtest"},
		&store.Config{Bucket: "boltDBTest"},
	)
	assert.NoError(t, err)
	assert.NotNil(t, kv)

	if _, ok := kv.(*BoltDB); !ok {
		t.Fatal("Error registering and initializing boltDB")
	}

	_ = os.Remove("/tmp/not_exist_dir/__boltdbtest")
}
Пример #28
0
func (provider *Kv) provide(configurationChan chan<- types.ConfigMessage) error {
	kv, err := libkv.NewStore(
		provider.StoreType,
		[]string{provider.Endpoint},
		&store.Config{
			ConnectionTimeout: 30 * time.Second,
			Bucket:            "traefik",
		},
	)
	if err != nil {
		return err
	}
	if _, err := kv.List(""); err != nil {
		return err
	}
	provider.kvclient = kv
	if provider.Watch {
		stopCh := make(chan struct{})
		chanKeys, err := kv.WatchTree(provider.Prefix, stopCh)
		if err != nil {
			return err
		}
		go func() {
			for {
				<-chanKeys
				configuration := provider.loadConfig()
				if configuration != nil {
					configurationChan <- types.ConfigMessage{
						ProviderName:  string(provider.StoreType),
						Configuration: configuration,
					}
				}
				defer close(stopCh)
			}
		}()
	}
	configuration := provider.loadConfig()
	configurationChan <- types.ConfigMessage{
		ProviderName:  string(provider.StoreType),
		Configuration: configuration,
	}
	return nil
}
Пример #29
0
func (provider *Kv) createStore() (store.Store, error) {
	storeConfig := &store.Config{
		ConnectionTimeout: 30 * time.Second,
		Bucket:            "traefik",
	}

	if provider.TLS != nil {
		var err error
		storeConfig.TLS, err = provider.TLS.CreateTLSConfig()
		if err != nil {
			return nil, err
		}
	}
	return libkv.NewStore(
		provider.storeType,
		strings.Split(provider.Endpoint, ","),
		storeConfig,
	)
}
Пример #30
0
func NewStore(backend string, machines []string, a *AgentCommand, keyspace string) *Store {
	s, err := libkv.NewStore(store.Backend(backend), machines, nil)
	if err != nil {
		log.Fatal(err)
	}

	log.WithFields(logrus.Fields{
		"backend":  backend,
		"machines": machines,
		"keyspace": keyspace,
	}).Debug("store: Backend config")

	_, err = s.List(keyspace)
	if err != store.ErrKeyNotFound && err != nil {
		log.WithError(err).Fatal("store: Store backend not reachable")
	}

	return &Store{Client: s, agent: a, keyspace: keyspace, backend: backend}
}