func ExampleLease_create() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() kvc := clientv3.NewKV(cli) lapi := clientv3.NewLease(cli) defer lapi.Close() // minimum lease TTL is 5-second resp, err := lapi.Create(context.TODO(), 5) if err != nil { log.Fatal(err) } // after 5 seconds, the key 'foo' will be removed _, err = kvc.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } }
func ExampleLease_keepAliveOnce() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Grant(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // to renew the lease only once _, err = cli.KeepAliveOnce(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) } }
func ExampleMaintenance_status() { for _, ep := range endpoints { cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{ep}, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() // resp, err := cli.Status(context.Background(), ep) // // or // mapi := clientv3.NewMaintenance(cli) resp, err := mapi.Status(context.Background(), ep) if err != nil { log.Fatal(err) } fmt.Printf("endpoint: %s / IsLeader: %v\n", ep, resp.Header.MemberId == resp.Leader) } // endpoint: localhost:2379 / IsLeader: false // endpoint: localhost:22379 / IsLeader: false // endpoint: localhost:32379 / IsLeader: true }
func ExampleLease_keepAlive() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Grant(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(resp.ID)) if err != nil { log.Fatal(err) } // the key 'foo' will be kept forever ch, kaerr := cli.KeepAlive(context.TODO(), resp.ID) if kaerr != nil { log.Fatal(kaerr) } ka := <-ch fmt.Println("ttl:", ka.TTL) // Output: ttl: 5 }
func ExampleLease_keepAliveOnce() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Grant(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(resp.ID)) if err != nil { log.Fatal(err) } // to renew the lease only once ka, kaerr := cli.KeepAliveOnce(context.TODO(), resp.ID) if kaerr != nil { log.Fatal(kaerr) } fmt.Println("ttl:", ka.TTL) // Output: ttl: 5 }
func (c *cluster) checkCompact(rev int64) error { if rev == 0 { return nil } for _, u := range c.GRPCURLs { cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{u}, DialTimeout: 5 * time.Second, }) if err != nil { return fmt.Errorf("%v (endpoint %s)", err, u) } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) wch := cli.Watch(ctx, "\x00", clientv3.WithFromKey(), clientv3.WithRev(rev-1)) wr, ok := <-wch cancel() cli.Close() if !ok { return fmt.Errorf("watch channel terminated (endpoint %s)", u) } if wr.CompactRevision != rev { return fmt.Errorf("got compact revision %v, wanted %v (endpoint %s)", wr.CompactRevision, rev, u) } } return nil }
// GetLeader returns the index of leader and error if any. func (c *cluster) GetLeader() (int, error) { if c.v2Only { return 0, nil } for i, ep := range c.GRPCURLs { cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{ep}, DialTimeout: 5 * time.Second, }) if err != nil { return 0, err } defer cli.Close() mapi := clientv3.NewMaintenance(cli) resp, err := mapi.Status(context.Background(), ep) if err != nil { return 0, err } if resp.Header.MemberId == resp.Leader { return i, nil } } return 0, fmt.Errorf("no leader found") }
func ExampleKV_getWithRev() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() presp, err := cli.Put(context.TODO(), "foo", "bar1") if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar2") if err != nil { log.Fatal(err) } ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := cli.Get(ctx, "foo", clientv3.WithRev(presp.Header.Revision)) cancel() if err != nil { log.Fatal(err) } for _, ev := range resp.Kvs { fmt.Printf("%s : %s\n", ev.Key, ev.Value) } // Output: foo : bar1 }
func newETCD3Storage(c storagebackend.Config) (storage.Interface, error) { tlsInfo := transport.TLSInfo{ CertFile: c.CertFile, KeyFile: c.KeyFile, CAFile: c.CAFile, } tlsConfig, err := tlsInfo.ClientConfig() if err != nil { return nil, err } // NOTE: Client relies on nil tlsConfig // for non-secure connections, update the implicit variable if len(c.CertFile) == 0 && len(c.KeyFile) == 0 && len(c.CAFile) == 0 { tlsConfig = nil } cfg := clientv3.Config{ Endpoints: c.ServerList, TLS: tlsConfig, } client, err := clientv3.New(cfg) if err != nil { return nil, err } etcd3.StartCompactor(context.Background(), client) return etcd3.New(client, c.Codec, c.Prefix), nil }
func ExampleConfig_withTLS() { tlsInfo := transport.TLSInfo{ CertFile: "/tmp/test-certs/test-name-1.pem", KeyFile: "/tmp/test-certs/test-name-1-key.pem", TrustedCAFile: "/tmp/test-certs/trusted-ca.pem", } tlsConfig, err := tlsInfo.ClientConfig() if err != nil { log.Fatal(err) } cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, TLS: tlsConfig, }) if err != nil { log.Fatal(err) } defer cli.Close() // make sure to close the client _, err = cli.Put(context.TODO(), "foo", "bar") if err != nil { log.Fatal(err) } }
func setRing(cfg torus.Config, r torus.Ring) error { client, err := etcdv3.New(etcdv3.Config{Endpoints: []string{cfg.MetadataAddress}, TLS: cfg.TLS}) if err != nil { return err } defer client.Close() resp, err := client.Get(context.Background(), MkKey("meta", "the-one-ring")) if err != nil { return err } if len(resp.Kvs) == 0 { return torus.ErrNoGlobalMetadata } oldr, err := ring.Unmarshal(resp.Kvs[0].Value) if err != nil { return err } if oldr.Version() != r.Version()-1 { return torus.ErrNonSequentialRing } b, err := r.Marshal() if err != nil { return err } _, err = client.Put(context.Background(), MkKey("meta", "the-one-ring"), string(b)) return err }
func newKVProxyServer(endpoints []string, t *testing.T) *kvproxyTestServer { cfg := clientv3.Config{ Endpoints: endpoints, DialTimeout: 5 * time.Second, } client, err := clientv3.New(cfg) if err != nil { t.Fatal(err) } kvp := NewKvProxy(client) kvts := &kvproxyTestServer{ kp: kvp, } var opts []grpc.ServerOption kvts.server = grpc.NewServer(opts...) pb.RegisterKVServer(kvts.server, kvts.kp) kvts.l, err = net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } go kvts.server.Serve(kvts.l) return kvts }
func newETCD3Storage(c storagebackend.Config) (storage.Interface, DestroyFunc, error) { tlsInfo := transport.TLSInfo{ CertFile: c.CertFile, KeyFile: c.KeyFile, CAFile: c.CAFile, } tlsConfig, err := tlsInfo.ClientConfig() if err != nil { return nil, nil, err } // NOTE: Client relies on nil tlsConfig // for non-secure connections, update the implicit variable if len(c.CertFile) == 0 && len(c.KeyFile) == 0 && len(c.CAFile) == 0 { tlsConfig = nil } cfg := clientv3.Config{ Endpoints: c.ServerList, TLS: tlsConfig, } client, err := clientv3.New(cfg) if err != nil { return nil, nil, err } ctx, cancel := context.WithCancel(context.Background()) etcd3.StartCompactor(ctx, client) destroyFunc := func() { cancel() client.Close() } if c.Quorum { return etcd3.New(client, c.Codec, c.Prefix), destroyFunc, nil } return etcd3.NewWithNoQuorumRead(client, c.Codec, c.Prefix), destroyFunc, nil }
func newEtcdClient(theEndpoints, certFile, keyFile, caFile string) (*clientv3.Client, error) { // Log the etcd endpoint for debugging purposes logger.Infof("ETCD Endpoints: %s", theEndpoints) // ETCD config etcdConfig := clientv3.Config{ Endpoints: strings.Split(theEndpoints, ","), DialTimeout: dialTimeout, } // Optionally, configure TLS transport if certFile != "" && keyFile != "" && caFile != "" { // Load client cert tlsInfo := transport.TLSInfo{ CertFile: certFile, KeyFile: keyFile, TrustedCAFile: caFile, } // Setup HTTPS client tlsConfig, err := tlsInfo.ClientConfig() if err != nil { return nil, err } // Add TLS config etcdConfig.TLS = tlsConfig } // ETCD client return clientv3.New(etcdConfig) }
func main() { cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{"127.0.0.1"}, DialTimeout: 5 * time.Second, }) if err != nil { log.Fatal(err) } defer cli.Close() _, err = cli.Put(context.TODO(), "foo", "bar") if err != nil { log.Fatal(err) } ctx, cancel := context.WithTimeout(context.Background(), time.Second) resp, err := cli.Get(ctx, "foo") cancel() if err != nil { log.Fatal(err) } for _, ev := range resp.Kvs { fmt.Printf("%s : %s\n", ev.Key, ev.Value) } }
func ExampleKV_putErrorHandling() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) _, err = cli.Put(ctx, "", "sample_value") cancel() if err != nil { switch err { case context.Canceled: fmt.Printf("ctx is canceled by another routine: %v\n", err) case context.DeadlineExceeded: fmt.Printf("ctx is attached with a deadline is exceeded: %v\n", err) case rpctypes.ErrEmptyKey: fmt.Printf("client-side error: %v\n", err) default: fmt.Printf("bad cluster endpoints, which are not etcd servers: %v\n", err) } } // Output: client-side error: etcdserver: key is not provided }
func ExampleKV_delete() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) defer cancel() // count keys about to be deleted gresp, err := cli.Get(ctx, "key", clientv3.WithPrefix()) if err != nil { log.Fatal(err) } // delete the keys dresp, err := cli.Delete(ctx, "key", clientv3.WithPrefix()) if err != nil { log.Fatal(err) } fmt.Println("Deleted all keys:", int64(len(gresp.Kvs)) == dresp.Deleted) // Output: // Deleted all keys: true }
// TestKVGetOneEndpointDown ensures a client can connect and get if one endpoint is down func TestKVPutOneEndpointDown(t *testing.T) { defer testutil.AfterTest(t) clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3}) defer clus.Terminate(t) // get endpoint list eps := make([]string, 3) for i := range eps { eps[i] = clus.Members[i].GRPCAddr() } // make a dead node clus.Members[rand.Intn(len(eps))].Stop(t) // try to connect with dead node in the endpoint list cfg := clientv3.Config{Endpoints: eps, DialTimeout: 1 * time.Second} cli, err := clientv3.New(cfg) if err != nil { t.Fatal(err) } defer cli.Close() ctx, cancel := context.WithTimeout(context.TODO(), 3*time.Second) if _, err := cli.Get(ctx, "abc", clientv3.WithSerializable()); err != nil { t.Fatal(err) } cancel() }
// TestDialSetEndpoints ensures SetEndpoints can replace unavailable endpoints with available ones. func TestDialSetEndpoints(t *testing.T) { defer testutil.AfterTest(t) clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3}) defer clus.Terminate(t) // get endpoint list eps := make([]string, 3) for i := range eps { eps[i] = clus.Members[i].GRPCAddr() } toKill := rand.Intn(len(eps)) cfg := clientv3.Config{Endpoints: []string{eps[toKill]}, DialTimeout: 1 * time.Second} cli, err := clientv3.New(cfg) if err != nil { t.Fatal(err) } defer cli.Close() // make a dead node clus.Members[toKill].Stop(t) clus.WaitLeader(t) // update client with available endpoints cli.SetEndpoints(eps[(toKill+1)%3]) ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) if _, err = cli.Get(ctx, "foo", clientv3.WithSerializable()); err != nil { t.Fatal(err) } cancel() }
func ExampleKV_getSortedPrefix() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() kvc := clientv3.NewKV(cli) for i := range make([]int, 3) { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) _, err = kvc.Put(ctx, fmt.Sprintf("key_%d", i), "value") cancel() if err != nil { log.Fatal(err) } } ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := kvc.Get(ctx, "key", clientv3.WithPrefix(), clientv3.WithSort(clientv3.SortByKey, clientv3.SortDescend)) cancel() if err != nil { log.Fatal(err) } for _, ev := range resp.Kvs { fmt.Printf("%s : %s\n", ev.Key, ev.Value) } // key_2 : value // key_1 : value // key_0 : value }
func newEtcdMetadata(cfg torus.Config) (torus.MetadataService, error) { uuid, err := metadata.MakeOrGetUUID(cfg.DataDir) if err != nil { return nil, err } v3cfg := etcdv3.Config{Endpoints: []string{cfg.MetadataAddress}} client, err := etcdv3.New(v3cfg) if err != nil { return nil, err } e := &Etcd{ cfg: cfg, Client: client, volumesCache: make(map[string]*models.Volume), uuid: uuid, } e.etcdCtx.etcd = e err = e.getGlobalMetadata() if err != nil { return nil, err } if err = e.watchRingUpdates(); err != nil { return nil, err } return e, nil }
func ExampleKV_compact() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() kvc := clientv3.NewKV(cli) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := kvc.Get(ctx, "foo") cancel() if err != nil { log.Fatal(err) } compRev := resp.Header.Revision // specify compact revision of your choice ctx, cancel = context.WithTimeout(context.Background(), requestTimeout) err = kvc.Compact(ctx, compRev) cancel() if err != nil { log.Fatal(err) } }
func ExampleKV_get() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() kvc := clientv3.NewKV(cli) _, err = kvc.Put(context.TODO(), "foo", "bar") if err != nil { log.Fatal(err) } ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := kvc.Get(ctx, "foo") cancel() if err != nil { log.Fatal(err) } for _, ev := range resp.Kvs { fmt.Printf("%s : %s\n", ev.Key, ev.Value) } // foo : bar }
func mustClient(endpoint, cert, key, cacert string) *clientv3.Client { // set tls if any one tls option set var cfgtls *transport.TLSInfo tls := transport.TLSInfo{} var file string if cert != "" { tls.CertFile = cert cfgtls = &tls } if key != "" { tls.KeyFile = key cfgtls = &tls } if cacert != "" { tls.CAFile = file cfgtls = &tls } cfg := clientv3.Config{ Endpoints: []string{endpoint}, TLS: cfgtls, DialTimeout: 20 * time.Second, } client, err := clientv3.New(cfg) if err != nil { ExitWithError(ExitBadConnection, err) } return client }
func mustCreateConn() *clientv3.Client { endpoint := endpoints[dialTotal%len(endpoints)] dialTotal++ cfg := clientv3.Config{Endpoints: []string{endpoint}} if !tls.Empty() { cfgtls, err := tls.ClientConfig() if err != nil { fmt.Fprintf(os.Stderr, "bad tls config: %v\n", err) os.Exit(1) } cfg.TLS = cfgtls } if len(user) != 0 { splitted := strings.SplitN(user, ":", 2) if len(splitted) != 2 { fmt.Fprintf(os.Stderr, "bad user information: %s\n", user) os.Exit(1) } cfg.Username = splitted[0] cfg.Password = splitted[1] } client, err := clientv3.New(cfg) if err != nil { fmt.Fprintf(os.Stderr, "dial error: %v\n", err) os.Exit(1) } return client }
func ExampleLease_keepAlive() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Create(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // the key 'foo' will be kept forever _, err = cli.KeepAlive(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) } }
func ExampleLease_revoke() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Create(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // revoking lease expires the key attached to its lease ID _, err = cli.Revoke(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) } gresp, err := cli.Get(context.TODO(), "foo") if err != nil { log.Fatal(err) } fmt.Println("number of keys:", len(gresp.Kvs)) // number of keys: 0 }
func mustClient(cmd *cobra.Command) *clientv3.Client { endpoint, err := cmd.Flags().GetString("endpoint") if err != nil { ExitWithError(ExitError, err) } // set tls if any one tls option set var cfgtls *transport.TLSInfo tls := transport.TLSInfo{} if tls.CertFile, err = cmd.Flags().GetString("cert"); err == nil { cfgtls = &tls } if tls.KeyFile, err = cmd.Flags().GetString("key"); err == nil { cfgtls = &tls } if tls.CAFile, err = cmd.Flags().GetString("cacert"); err == nil { cfgtls = &tls } cfg := clientv3.Config{ Endpoints: []string{endpoint}, TLS: cfgtls, } client, err := clientv3.New(cfg) if err != nil { ExitWithError(ExitBadConnection, err) } return client }
func startGRPCProxy(cmd *cobra.Command, args []string) { l, err := net.Listen("tcp", grpcProxyListenAddr) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } cfg, err := newClientCfg() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } client, err := clientv3.New(*cfg) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } kvp := grpcproxy.NewKvProxy(client) watchp := grpcproxy.NewWatchProxy(client) server := grpc.NewServer() pb.RegisterKVServer(server, kvp) pb.RegisterWatchServer(server, watchp) server.Serve(l) }
func newClientV3(cfg clientv3.Config) (*clientv3.Client, error) { c, err := clientv3.New(cfg) if err != nil { return nil, err } rpc := toGRPC(c) c.KV = clientv3.NewKVFromKVClient(rpc.KV) c.Watcher = clientv3.NewWatchFromWatchClient(rpc.Watch) return c, nil }