etcd for rust

Overview

etcd for Rust

CI Status Crates.io License

An etcd(API v3) client for Rust, and it provides async/await APIs backed by tokio and tonic.

Documentation on the library can be found at docs.rs/etcd-rs.

Features

  • Asynchronous
  • Etcd APIv3

Examples

./examples

Usage

Add following dependencies in your project cargo.toml:

[dependencies]
etcd-rs = "0.5"

Setup Client

let endpoints = vec!["http://127.0.0.1:2379".to_owned()];

let client = Client::connect(ClientConfig {
    endpoints,
    auth: None,
    tls: None
}).await;

if authenticate enabled

let endpoints = vec!["http://127.0.0.1:2379".to_owned()];

let client = Client::connect(ClientConfig {
    endpoints,
    auth: Some(("user".to_owned(), "password".to_owned())),
    tls: None
}).await;

with tls

let endpoints = vec!["https://127.0.0.1:2379".to_owned()];
let tls = ClientTlsConfig::new();

let client = Client::connect(ClientConfig {
    endpoints,
    auth: Some(("user".to_owned(), "password".to_owned())),
    tls: Some(tls)
}).await;

License

This project is licensed under the MIT license.

Comments
  • Manage lifetime of tunnel objects/tasks

    Manage lifetime of tunnel objects/tasks

    Hi! This should fix #25.

    It follows roughly the approach I mentioned there: a RwLock with a oneshot::channel for telling the spawned tasks to shutdown.

    I have some tests on the code I introduced, and the examples all still run. Notably, I've stopped seeing the panics.

    Happy for any feedback, thanks!

    opened by znewman01 6
  • How do I add a cluster?

    How do I add a cluster?

    How do I add a cluster to the client?

    let etcd_adress = vec![
            "127.0.0.1:23791".to_owned(),
            "127.0.0.1:23792".to_owned(),
            "127.0.0.1:23793".to_owned(),
        ]
    Client::builder().endpoints(etcd_adress.clone()).build()
    

    returns: RpcFailure(RpcStatus { status: Unavailable, details: Some("Name resolution failure") })

    but Client::builder().add_endpoint( "127.0.0.1:23791").build() with each of the upper ips works.

    FYI this is the docker-compose I use to start the cluster:

    version: '3'
    
    services:
    
      etcd1:
        image: quay.io/coreos/etcd:latest
        environment:
                ETCD_NAME: node1
    
                ETCD_ADVERTISE_CLIENT_URLS: http://etcd1:2379
                ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
    
                ETCD_INITIAL_ADVERTISE_PEER_URLS: http://etcd1:2380
                ETCD_LISTEN_PEER_URLS: http://0.0.0.0:2380
    
                ETCD_DATA_DIR: /etcd-data/etcd1.etcd
                ETCDCTL_API: 3
                ETCD_DEBUG: 1
                
                ETCD_INITIAL_CLUSTER: node3=http://etcd3:2380,node1=http://etcd1:2380,node2=http://etcd2:2380
                ETCD_INITIAL_CLUSTER_STATE: new
                ETCD_INITIAL_CLUSTER_TOKEN: etcd-ftw           
        ports:
          - 23791:2379
          - 23801:2380
    
    
      etcd2:
        image: quay.io/coreos/etcd:latest
        environment:
                ETCD_NAME: node2
    
                ETCD_INITIAL_ADVERTISE_PEER_URLS: http://etcd2:2380
                ETCD_LISTEN_PEER_URLS: http://0.0.0.0:2380
    
                ETCD_ADVERTISE_CLIENT_URLS: http://etcd2:2379
                ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
                
                ETCD_DATA_DIR: /etcd-data/etcd2.etcd
                ETCDCTL_API: 3
                ETCD_DEBUG: 1
    
                ETCD_INITIAL_CLUSTER: node3=http://etcd3:2380,node1=http://etcd1:2380,node2=http://etcd2:2380
                ETCD_INITIAL_CLUSTER_STATE: new
                ETCD_INITIAL_CLUSTER_TOKEN: etcd-ftw
        ports:
          - 23792:2379
          - 23802:2380
    
    
      etcd3:
        image: quay.io/coreos/etcd:latest
        environment:
                ETCD_NAME: node3
    
                ETCD_INITIAL_ADVERTISE_PEER_URLS: http://etcd3:2380
                ETCD_LISTEN_PEER_URLS: http://0.0.0.0:2380
                
                ETCD_ADVERTISE_CLIENT_URLS: http://etcd3:2379
                ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
                
    
                ETCD_DATA_DIR: /etcd-data/etcd3.etcd
                ETCDCTL_API: 3
                ETCD_DEBUG: 1
                
                ETCD_INITIAL_CLUSTER: node3=http://etcd3:2380,node1=http://etcd1:2380,node2=http://etcd2:2380
                ETCD_INITIAL_CLUSTER_STATE: new
                ETCD_INITIAL_CLUSTER_TOKEN: etcd-ftw
        ports:
          - 23793:2379
          - 23803:2380
    

    Thanks in Advance!

    wontfix 
    opened by florianeichin 6
  • memory leak when connect interuped

    memory leak when connect interuped

    at debug model,a lot of debug message print in log:

    tonic-0.4.3/src/codec/decode.rs-> line:231]  decoder inner stream error: Status { code: Unknown, message: "h2 protocol error: broken pipe" } 
    

    at the same time, memory using by tonic rise up and stand there,every time interupt appeared,memory usage upgrade.

    opened by elderbig 5
  • Upgrade tonic to 0.5, prost to 0.8, and bump version to 0.6.0

    Upgrade tonic to 0.5, prost to 0.8, and bump version to 0.6.0

    This PR:

    • Upgrades tonic to 0.5
    • Upgrades prost to 0.8 (fixes https://rustsec.org/advisories/RUSTSEC-2021-0073.html )
    • Bumps version to 0.6.0

    Part of the new version of tonic is that they messed up the types for interceptors, so they were moved up an abstraction layer into the Auth/Lease/etc components.

    wontfix 
    opened by Protryon 4
  • Reduce code duplication + export TxnOp

    Reduce code duplication + export TxnOp

    (this adds an export of TxnOp, at least to make the documentation less confusing)

    Fixes #43.

    Additionally, this removes the take methods on KeyRange and instead makes the fields public. This improves usability, but breaks API compatibility.

    opened by zseri 4
  • Updated the proto support, fixed some perf issues and a few more things

    Updated the proto support, fixed some perf issues and a few more things

    Hey :wave:!

    Here's what I did in this PR:

    • The proto files were updated and a build.rs file to generate Rust code for them was added.
    • The requests and responses were updated to support newly added fields.
    • A few unwraps were removed to return Result instead.
    • Support for using Vec<u8> as keys and values was added.
    • Clients are now all Cloneable and requests and responses (and their related types) now are Debugable and Cloneable.
    • A KeepAlive stream has been added. It is returned by one of two new methods of LeaseClient: keep_alive and keep_alive_at_interval (keep_alive_once has been removed).

    Closes #6

    opened by r3v2d0g 4
  • use it has err Service was not ready

    use it has err Service was not ready

    first thanks for your work !

    I started etcd ok , the restful can used .

    bu when use this client it report:

    "grpc-status: Unknown, grpc-message: \"Service was not ready: transport error: buffer\\\'s worker closed unexpectedly\""`', src/etcd_client.rs:179:13
    stack backtrace:
       0: backtrace::backtrace::libunwind::trace
                 at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
       1: backtrace::backtrace::trace_unsynchronized
                 at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
       2: std::sys_common::backtrace::_print_fmt
                 at src/libstd/sys_common/backtrace.rs:77
       3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
                 at src/libstd/sys_common/backtrace.rs:59
       4: core::fmt::write
                 at src/libcore/fmt/mod.rs:1052
       5: std::io::Write::write_fmt
                 at /rustc/41f41b2354778375dc72f7ed1d9323626580dc4d/src/libstd/io/mod.rs:1426
       6: std::io::impls::<impl std::io::Write for alloc::boxed::Box<W>>::write_fmt
                 at src/libstd/io/impls.rs:156
       7: std::sys_common::backtrace::_print
                 at src/libstd/sys_common/backtrace.rs:62
       8: std::sys_common::backtrace::print
                 at src/libstd/sys_common/backtrace.rs:49
       9: std::panicking::default_hook::{{closure}}
                 at src/libstd/panicking.rs:204
      10: std::panicking::default_hook
                 at src/libstd/panicking.rs:221
      11: std::panicking::rust_panic_with_hook
                 at src/libstd/panicking.rs:472
      12: rust_begin_unwind
                 at src/libstd/panicking.rs:380
      13: std::panicking::begin_panic_fmt
                 at src/libstd/panicking.rs:334
      14: any_client::etcd_client::test_etcd_kv
                 at src/etcd_client.rs:179
      15: any_client::etcd_client::test_etcd_kv::{{closure}}
                 at src/etcd_client.rs:173
      16: core::ops::function::FnOnce::call_once
                 at /rustc/41f41b2354778375dc72f7ed1d9323626580dc4d/src/libcore/ops/function.rs:232
      17: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
                 at /rustc/41f41b2354778375dc72f7ed1d9323626580dc4d/src/liballoc/boxed.rs:1015
      18: __rust_maybe_catch_panic
                 at src/libpanic_unwind/lib.rs:86
      19: std::panicking::try
                 at /rustc/41f41b2354778375dc72f7ed1d9323626580dc4d/src/libstd/panicking.rs:281
      20: std::panic::catch_unwind
                 at /rustc/41f41b2354778375dc72f7ed1d9323626580dc4d/src/libstd/panic.rs:394
      21: test::run_test_in_process
                 at src/libtest/lib.rs:539
      22: test::run_test::run_test_inner::{{closure}}
                 at src/libtest/lib.rs:452
    

    my code is

    // new client 
     pub fn new(addr: &str) -> EtcdCli {
            match Runtime::new()
                .unwrap()
                .block_on(Client::connect(ClientConfig {
                    endpoints: vec![addr.to_owned()],
                    auth: None,
                })) {
                Ok(c) => EtcdCli { client: c },
                Err(e) => panic!("conn master server has err:{}", e.to_string()),
            }
        }
    
    
    //set
    
    pub fn set(&self, key: &str, value: &str, ttl: u64) -> ASResult<KValue> {
            let mut req = PutRequest::new(key, value);
            req.set_lease(ttl);
            match Runtime::new().unwrap().block_on(self.client.kv().put(req)) {
                Ok(mut r) => match r.take_prev_kv() {
                    Some(kv) => {
                        return Ok(KValue {
                            key: kv.key_str().to_string(),
                            value: kv.value_str().to_string(),
                        })
                    }
                    None => return Err(err_generic()),
                },
                Err(e) => {
                    return Err(err_code(INTERNAL_ERR, e.to_string()));
                }
            }
        }
    
    opened by ansjsun 3
  • feat(watch): set `hasleader` metadata

    feat(watch): set `hasleader` metadata

    According to comment of Watcher in etcd repo

    In order to prevent a watch stream being stuck in a partitioned node, make sure to wrap context with "WithRequireLeader".

    The WithRequireLeader function set the metadata hasleader to true, and etcdctl has done this, so maybe we should do the same? Another way is to provide a function to set metadata of requests, but I believe set hasleader in watch is what etcd recommended since it's crucial to know if the current etcd endpoint is working properly or not.

    opened by Direktor799 2
  • Tonic conflict

    Tonic conflict

    Hello,

    I'm using tonic 0.7.1 for my project but etcd-rs is using tonic 0.6 and this is causing a conflict. Is there a way to address this? It does look like there is some breaking changes, at least in module visibility in tonic.

    opened by diggyk 2
  • client watch multiple key range will panic

    client watch multiple key range will panic

    panic position:

     thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', etcd-rs/src/watch/mod.rs:182:66
    

    watch.tunnel.resp_receiver can not take again:

    tunnel.resp_receiver.take()
    
    opened by SSebo 2
  • panicked when some etcd server node shutdown

    panicked when some etcd server node shutdown

    panicked logs

    thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Status { code: Unknown, message: "transport error: error trying to connect: tcp connect error: Connection refused (os error 111)" }', .../etcd-rs-0.5.0/src/lease/mod.rs:109:70
    

    code in crate

    res = client.lease_keep_alive(request).fuse() => res.unwrap().into_inner()
    
    opened by elderbig 2
  • connect_with_token doesn't need to be async?

    connect_with_token doesn't need to be async?

    Looking through the code (v1.0.0-alpha.3), it seems like Client::connect_with_token doesn't actually await anything. Maybe there are plans to do some async work here in the future? If not it would be nice if this could be made sync

    opened by jamesbirtles 0
  • Handle edge case where all node(s) may be unavailable.

    Handle edge case where all node(s) may be unavailable.

    We're using this in a scenario where we resolve the endpoints from a dns entry. It would be nice to be able to have something like this baked into the library, so that in the event all nodes become unavailable, the library can recover by querying the dns entry again.

    opened by dtzxporter 1
Releases(v1.0.0)
Owner
ccc
ccc
🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, SQLite, and MSSQL.

SQLx ?? The Rust SQL Toolkit Install | Usage | Docs Built with ❤️ by The LaunchBadge team SQLx is an async, pure Rust† SQL crate featuring compile-tim

launchbadge 7.6k Dec 31, 2022
Redis re-implemented in Rust.

rsedis Redis re-implemented in Rust. Why? To learn Rust. Use Cases rsedis does not rely on UNIX-specific features. Windows users can run it as a repla

Sebastian Waisbrot 1.6k Jan 6, 2023
A generic connection pool for Rust

r2d2 A generic connection pool for Rust. Documentation Opening a new database connection every time one is needed is both inefficient and can lead to

Steven Fackler 1.2k Jan 8, 2023
An ArangoDB driver for Rust

Rincon Rincon is an ArangoDB driver for Rust. It enables low level access to ArangoDB in a typesafe and Rust idiomatic manner. The name Rincon is deri

Innoave 35 Mar 21, 2021
Cassandra DB native client written in Rust language. Find 1.x versions on https://github.com/AlexPikalov/cdrs/tree/v.1.x Looking for an async version? - Check WIP https://github.com/AlexPikalov/cdrs-async

CDRS CDRS is looking for maintainers CDRS is Apache Cassandra driver written in pure Rust. ?? Looking for an async version? async-std https://github.c

Alex Pikalov 338 Jan 1, 2023
Cassandra (CQL) driver for Rust, using the DataStax C/C++ driver under the covers.

cassandra-cpp This is a maintained Rust project that exposes the DataStax cpp driver at https://github.com/datastax/cpp-driver/ in a somewhat-sane cra

null 93 Jan 7, 2023
CouchDB client-side library for the Rust programming language

Chill Chill is a client-side CouchDB library for the Rust programming language, available on crates.io. It targets Rust Stable. Chill's three chief de

null 35 Jun 26, 2022
Sofa - CouchDB for Rust

Sofa - CouchDB for Rust Documentation Here: http://docs.rs/sofa Installation [dependencies] sofa = "0.6" Description This crate is an interface to Cou

66 Origin 40 Feb 11, 2022
⚡🦀 🧨 make your rust types fit DynamoDB and visa versa

?? ?? dynomite dynomite makes DynamoDB fit your types (and visa versa) Overview Goals ⚡ make writing dynamodb applications in rust a productive experi

Doug Tangren 197 Dec 15, 2022
A Rust client for the ElasticSearch REST API

rs-es Introduction An ElasticSearch client for Rust via the REST API. Targetting ElasticSearch 2.0 and higher. Other clients For later versions of Ela

Ben Ashford 218 Dec 27, 2022
An Elasticsearch REST API client for Rust

elastic elastic is an efficient, modular API client for Elasticsearch written in Rust. The API is targeting the Elastic Stack 7.x. elastic provides st

null 249 Oct 18, 2022
Rust bindings for LMDB

lmdb-rs Rust bindings for LMDB Documentation (master branch) Building LMDB is bundled as submodule so update submodules first: git submodule update --

Valerii Hiora 104 Dec 8, 2022
The official MongoDB Rust Driver

MongoDB Rust Driver This repository contains the officially supported MongoDB Rust driver, a client side library that can be used to interact with Mon

mongodb 1.1k Dec 30, 2022
Redis library for rust

redis-rs Redis-rs is a high level redis library for Rust. It provides convenient access to all Redis functionality through a very flexible but low-lev

Armin Ronacher 2.8k Jan 8, 2023
rust wrapper for rocksdb

rust-rocksdb Requirements Clang and LLVM Contributing Feedback and pull requests welcome! If a particular feature of RocksDB is important to you, plea

null 1.3k Dec 30, 2022
UnQLite wrapper 1.0 is avaliable for Rust

unqlite A high-level UnQLite database engine wrapper. NOTE: Some of the documents is stolen from UnQLite Official Website. What is UnQLite? UnQLite is

Huo Linhe 101 Dec 12, 2022
Pure Rust library for Apache ZooKeeper built on MIO

rust-zookeeper Zookeeper client written 100% in Rust This library is intended to be equivalent with the official (low-level) ZooKeeper client which sh

Nándor István Krácser 168 Dec 25, 2022
PickleDB-rs is a lightweight and simple key-value store. It is a Rust version for Python's PickleDB

PickleDB PickleDB is a lightweight and simple key-value store written in Rust, heavily inspired by Python's PickleDB PickleDB is fun and easy to use u

null 155 Jan 5, 2023
TDS 7.2+ (mssql / Microsoft SQL Server) async driver for rust

Tiberius A native Microsoft SQL Server (TDS) client for Rust. Supported SQL Server versions Version Support level Notes 2019 Tested on CI 2017 Tested

Prisma 189 Dec 25, 2022