From 1f3c62301ffacb5558e4c28e85b1b0809d3b2124 Mon Sep 17 00:00:00 2001 From: Tao He Date: Wed, 22 Dec 2021 13:49:14 +0800 Subject: [PATCH] Allow specifying the auth token TTL when auth with password. Resolves #107. Signed-off-by: Tao He --- README.md | 7 ++ etcd/Client.hpp | 25 ++++++- etcd/KeepAlive.hpp | 14 ++-- etcd/SyncClient.hpp | 2 + etcd/Watcher.hpp | 12 ++-- src/Client.cpp | 169 +++++++++++++++++++++++++++++--------------- src/KeepAlive.cpp | 12 ++-- src/SyncClient.cpp | 3 +- src/Watcher.cpp | 24 ++++--- tst/CMakeLists.txt | 5 +- 10 files changed, 187 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 0d9b3cf..9f20166 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,13 @@ Or the etcd client can be constructed explicitly: "http://127.0.0.1:2379", "root", "root"); ``` +The default authentication token will be expired every 5 minutes (300 seconds), which is controlled by +the `--auth-token-ttl` flag of etcd. When constructing a etcd client, a customized TTL value is allow: + +```c++ + etcd::Client etcd("http://127.0.0.1:2379", "root", "root", 300); +``` + Enabling v3 authentication requires a bit more work for older versions etcd (etcd 3.2.x and etcd 3.3.x). First you need to set the `ETCDCTL_API=3`, then diff --git a/etcd/Client.hpp b/etcd/Client.hpp index 1ed4776..1e450a0 100644 --- a/etcd/Client.hpp +++ b/etcd/Client.hpp @@ -47,6 +47,13 @@ namespace etcd */ class Client { + private: + class TokenAuthenticator; + class TokenAuthenticatorDeleter { + public: + void operator()(TokenAuthenticator *authenticator); + }; + public: /** * Constructs an etcd client object. @@ -106,10 +113,12 @@ namespace etcd * @param username username of etcd auth * @param password password of etcd auth * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. + * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. */ Client(std::string const & etcd_url, std::string const & username, std::string const & password, + int const auth_token_ttl = 300, std::string const & load_balancer = "round_robin"); /** @@ -120,10 +129,13 @@ namespace etcd * @param username username of etcd auth * @param password password of etcd auth * @param arguments user provided grpc channel arguments. + * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. + * Default value should be 300. */ Client(std::string const & etcd_url, std::string const & username, std::string const & password, + int const auth_token_ttl, #if defined(WITH_GRPC_CHANNEL_CLASS) grpc::ChannelArguments const & arguments #else @@ -140,10 +152,12 @@ namespace etcd * @param username username of etcd auth * @param password password of etcd auth * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. + * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. */ static etcd::Client *WithUser(std::string const & etcd_url, std::string const & username, std::string const & password, + int const auth_token_ttl = 300, std::string const & load_balancer = "round_robin"); /** @@ -154,10 +168,13 @@ namespace etcd * @param username username of etcd auth * @param password password of etcd auth * @param arguments user provided grpc channel arguments. + * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. + * Default value should be 300. */ static etcd::Client *WithUser(std::string const & etcd_url, std::string const & username, std::string const & password, + int const auth_token_ttl, #if defined(WITH_GRPC_CHANNEL_CLASS) grpc::ChannelArguments const & arguments #else @@ -627,13 +644,19 @@ namespace etcd pplx::task resign(std::string const &name, int64_t lease_id, std::string const &key, int64_t revision); + /** + * Return current auth token. + */ + const std::string ¤t_auth_token() const; + private: #if defined(WITH_GRPC_CHANNEL_CLASS) std::shared_ptr channel; #else std::shared_ptr channel; #endif - std::string auth_token; + + mutable std::unique_ptr token_authenticator; struct EtcdServerStubs; struct EtcdServerStubsDeleter { diff --git a/etcd/KeepAlive.hpp b/etcd/KeepAlive.hpp index 65fab55..79fe637 100644 --- a/etcd/KeepAlive.hpp +++ b/etcd/KeepAlive.hpp @@ -27,23 +27,25 @@ namespace etcd { public: KeepAlive(Client const &client, - int ttl, int64_t lease_id=0); + int ttl, int64_t lease_id = 0); KeepAlive(std::string const & address, - int ttl, int64_t lease_id=0); + int ttl, int64_t lease_id = 0); KeepAlive(std::string const & address, std::string const & username, std::string const & password, - int ttl, int64_t lease_id=0); + int ttl, int64_t lease_id = 0, + int const auth_token_ttl = 300); KeepAlive(Client const &client, std::function const &handler, - int ttl, int64_t lease_id=0); + int ttl, int64_t lease_id = 0); KeepAlive(std::string const & address, std::function const &handler, - int ttl, int64_t lease_id=0); + int ttl, int64_t lease_id = 0); KeepAlive(std::string const & address, std::string const & username, std::string const & password, std::function const &handler, - int ttl, int64_t lease_id=0); + int ttl, int64_t lease_id = 0, + int const auth_token_ttl = 300); KeepAlive(KeepAlive const &) = delete; KeepAlive(KeepAlive &&) = delete; diff --git a/etcd/SyncClient.hpp b/etcd/SyncClient.hpp index eb00787..0a2fee9 100644 --- a/etcd/SyncClient.hpp +++ b/etcd/SyncClient.hpp @@ -34,10 +34,12 @@ namespace etcd * @param username username of etcd auth * @param password password of etcd auth * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. + * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. */ SyncClient(std::string const & etcd_url, std::string const & username, std::string const & password, + int const auth_token_ttl = 300, std::string const & load_balancer = "round_robin"); Response head(); diff --git a/etcd/Watcher.hpp b/etcd/Watcher.hpp index 1c5300f..366f6ed 100644 --- a/etcd/Watcher.hpp +++ b/etcd/Watcher.hpp @@ -37,19 +37,23 @@ namespace etcd Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, - std::function callback, bool recursive=false); + std::function callback, bool recursive=false, + int const auth_token_ttl = 300); Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, std::string const &range_end, - std::function callback); + std::function callback, + int const auth_token_ttl = 300); Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, int fromIndex, - std::function callback, bool recursive=false); + std::function callback, bool recursive=false, + int const auth_token_ttl = 300); Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, std::string const &range_end, int fromIndex, - std::function callback); + std::function callback, + int const auth_token_ttl = 300); Watcher(Watcher const &) = delete; Watcher(Watcher &&) = delete; diff --git a/src/Client.cpp b/src/Client.cpp index f1b0b07..f4d011e 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -165,6 +166,56 @@ static grpc::SslCredentialsOptions make_ssl_credentials(std::string const &ca, } } +class etcd::Client::TokenAuthenticator { + private: + std::shared_ptr channel_; + std::string username_, password_, token_; + int ttl_ = 300; // see also --auth-token-ttl for etcd + std::chrono::time_point updated_at; + std::mutex mtx_; + bool has_token_ = false; + + public: + TokenAuthenticator(): has_token_(false) { + } + + TokenAuthenticator(std::shared_ptr channel, + std::string const &username, + std::string const &password, + const int ttl=300) + : channel_(channel), username_(username), password_(password), ttl_(ttl), has_token_(false) { + if ((!username.empty()) && (!(password.empty()))) { + has_token_ = true; + renew_if_expired(true); + } + } + + std::string const &renew_if_expired(const bool force = false) { + if (!has_token_) { + return token_; + } + std::lock_guard scoped_lock(mtx_); + if (!token_.empty()) { + auto tp = std::chrono::system_clock::now(); + if (force || std::chrono::duration_cast(tp - updated_at).count() + > std::max(1, ttl_ - 3)) { + updated_at = tp; + // auth + if (!etcd::detail::authenticate(this->channel_, username_, password_, token_)) { + throw std::invalid_argument("Etcd authentication failed: " + token_); + } + } + } + return token_; + } +}; + +void etcd::Client::TokenAuthenticatorDeleter::operator()(etcd::Client::TokenAuthenticator *authenticator) { + if (authenticator) { + delete authenticator; + } +} + struct etcd::Client::EtcdServerStubs { std::unique_ptr kvServiceStub; std::unique_ptr watchServiceStub; @@ -190,6 +241,7 @@ etcd::Client::Client(std::string const & address, std::shared_ptr creds = grpc::InsecureChannelCredentials(); grpc_args.SetLoadBalancingPolicyName(load_balancer); this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); + this->token_authenticator.reset(new TokenAuthenticator()); // create stubs stubs.reset(new EtcdServerStubs{}); @@ -210,6 +262,7 @@ etcd::Client::Client(std::string const & address, grpc_args.SetMaxReceiveMessageSize(std::numeric_limits::max()); std::shared_ptr creds = grpc::InsecureChannelCredentials(); this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); + this->token_authenticator.reset(new TokenAuthenticator()); // create stubs stubs.reset(new EtcdServerStubs{}); @@ -233,6 +286,7 @@ etcd::Client *etcd::Client::WithUrl(std::string const & etcd_url, etcd::Client::Client(std::string const & address, std::string const & username, std::string const & password, + int const auth_token_ttl, std::string const & load_balancer) { // create channels @@ -245,11 +299,7 @@ etcd::Client::Client(std::string const & address, this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); // auth - std::string token_or_message; - if (!etcd::detail::authenticate(this->channel, username, password, token_or_message)) { - throw std::invalid_argument("Etcd authentication failed: " + token_or_message); - } - this->auth_token = token_or_message; + this->token_authenticator.reset(new TokenAuthenticator(this->channel, username, password, auth_token_ttl)); // setup stubs stubs.reset(new EtcdServerStubs{}); @@ -263,6 +313,7 @@ etcd::Client::Client(std::string const & address, etcd::Client::Client(std::string const & address, std::string const & username, std::string const & password, + int const auth_token_ttl, grpc::ChannelArguments const & arguments) { // create channels @@ -274,11 +325,7 @@ etcd::Client::Client(std::string const & address, this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); // auth - std::string token_or_message; - if (!etcd::detail::authenticate(this->channel, username, password, token_or_message)) { - throw std::invalid_argument("Etcd authentication failed: " + token_or_message); - } - this->auth_token = token_or_message; + this->token_authenticator.reset(new TokenAuthenticator(this->channel, username, password, auth_token_ttl)); // setup stubs stubs.reset(new EtcdServerStubs{}); @@ -290,17 +337,19 @@ etcd::Client::Client(std::string const & address, } etcd::Client *etcd::Client::WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - std::string const & load_balancer) { - return new etcd::Client(etcd_url, username, password, load_balancer); + std::string const & username, + std::string const & password, + int const auth_token_ttl, + std::string const & load_balancer) { + return new etcd::Client(etcd_url, username, password, auth_token_ttl, load_balancer); } etcd::Client *etcd::Client::WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - grpc::ChannelArguments const & arguments) { - return new etcd::Client(etcd_url, username, password, arguments); + std::string const & username, + std::string const & password, + int const auth_token_ttl, + grpc::ChannelArguments const & arguments) { + return new etcd::Client(etcd_url, username, password, auth_token_ttl, arguments); } @@ -323,6 +372,7 @@ etcd::Client::Client(std::string const & address, grpc_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, target_name_override); } this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); + this->token_authenticator.reset(new TokenAuthenticator()); // setup stubs stubs.reset(new EtcdServerStubs{}); @@ -351,6 +401,7 @@ etcd::Client::Client(std::string const & address, grpc_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, target_name_override); } this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); + this->token_authenticator.reset(new TokenAuthenticator()); // setup stubs stubs.reset(new EtcdServerStubs{}); @@ -382,7 +433,7 @@ etcd::Client *etcd::Client::WithSSL(std::string const & etcd_url, pplx::task etcd::Client::head() { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.kv_stub = stubs->kvServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncHeadAction(params)); return Response::create(call); @@ -391,7 +442,7 @@ pplx::task etcd::Client::head() pplx::task etcd::Client::get(std::string const & key) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.withPrefix = false; params.kv_stub = stubs->kvServiceStub.get(); @@ -402,7 +453,7 @@ pplx::task etcd::Client::get(std::string const & key) pplx::task etcd::Client::set(std::string const & key, std::string const & value, int ttl) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.kv_stub = stubs->kvServiceStub.get(); @@ -430,7 +481,7 @@ pplx::task etcd::Client::set(std::string const & key, std::strin pplx::task etcd::Client::set(std::string const & key, std::string const & value, int64_t leaseid) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.lease_id = leaseid; @@ -443,7 +494,7 @@ pplx::task etcd::Client::set(std::string const & key, std::strin pplx::task etcd::Client::add(std::string const & key, std::string const & value, int ttl) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.kv_stub = stubs->kvServiceStub.get(); @@ -470,7 +521,7 @@ pplx::task etcd::Client::add(std::string const & key, std::strin pplx::task etcd::Client::add(std::string const & key, std::string const & value, int64_t leaseid) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.lease_id = leaseid; @@ -491,7 +542,7 @@ pplx::task etcd::Client::put(std::string const & key, std::strin pplx::task etcd::Client::modify(std::string const & key, std::string const & value, int ttl) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.kv_stub = stubs->kvServiceStub.get(); @@ -518,7 +569,7 @@ pplx::task etcd::Client::modify(std::string const & key, std::st pplx::task etcd::Client::modify(std::string const & key, std::string const & value, int64_t leaseid) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.lease_id = leaseid; @@ -531,7 +582,7 @@ pplx::task etcd::Client::modify(std::string const & key, std::st pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value, int ttl) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.old_value.assign(old_value); @@ -560,7 +611,7 @@ pplx::task etcd::Client::modify_if(std::string const & key, std: pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value, int64_t leaseid) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.old_value.assign(old_value); @@ -574,7 +625,7 @@ pplx::task etcd::Client::modify_if(std::string const & key, std: pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, int64_t old_index, int ttl) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.old_revision = old_index; @@ -602,7 +653,7 @@ pplx::task etcd::Client::modify_if(std::string const & key, std: pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, int64_t old_index, int64_t leaseid) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.value.assign(value); params.lease_id = leaseid; @@ -617,7 +668,7 @@ pplx::task etcd::Client::modify_if(std::string const & key, std: pplx::task etcd::Client::rm(std::string const & key) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.withPrefix = false; params.kv_stub = stubs->kvServiceStub.get(); @@ -628,7 +679,7 @@ pplx::task etcd::Client::rm(std::string const & key) pplx::task etcd::Client::rm_if(std::string const & key, std::string const & old_value) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.old_value.assign(old_value); params.kv_stub = stubs->kvServiceStub.get(); @@ -640,7 +691,7 @@ pplx::task etcd::Client::rm_if(std::string const & key, std::str pplx::task etcd::Client::rm_if(std::string const & key, int64_t old_index) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.old_revision = old_index; params.kv_stub = stubs->kvServiceStub.get(); @@ -653,7 +704,7 @@ pplx::task etcd::Client::rm_if(std::string const & key, int64_t pplx::task etcd::Client::rmdir(std::string const & key, bool recursive) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.withPrefix = recursive; params.kv_stub = stubs->kvServiceStub.get(); @@ -669,7 +720,7 @@ pplx::task etcd::Client::rmdir(std::string const & key, const ch pplx::task etcd::Client::rmdir(std::string const & key, std::string const &range_end) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.range_end.assign(range_end); params.withPrefix = false; @@ -681,7 +732,7 @@ pplx::task etcd::Client::rmdir(std::string const & key, std::str pplx::task etcd::Client::ls(std::string const & key) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.withPrefix = true; params.limit = 0; // default no limit. @@ -693,7 +744,7 @@ pplx::task etcd::Client::ls(std::string const & key) pplx::task etcd::Client::ls(std::string const & key, size_t const limit) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.withPrefix = true; params.limit = limit; @@ -705,7 +756,7 @@ pplx::task etcd::Client::ls(std::string const & key, size_t cons pplx::task etcd::Client::ls(std::string const & key, std::string const &range_end) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.range_end.assign(range_end); params.withPrefix = false; @@ -718,7 +769,7 @@ pplx::task etcd::Client::ls(std::string const & key, std::string pplx::task etcd::Client::ls(std::string const & key, std::string const &range_end, size_t const limit) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.range_end.assign(range_end); params.withPrefix = false; @@ -731,7 +782,7 @@ pplx::task etcd::Client::ls(std::string const & key, std::string pplx::task etcd::Client::watch(std::string const & key, bool recursive) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.withPrefix = recursive; params.watch_stub = stubs->watchServiceStub.get(); @@ -742,7 +793,7 @@ pplx::task etcd::Client::watch(std::string const & key, bool rec pplx::task etcd::Client::watch(std::string const & key, int64_t fromIndex, bool recursive) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.withPrefix = recursive; params.revision = fromIndex; @@ -759,7 +810,7 @@ pplx::task etcd::Client::watch(std::string const & key, const ch pplx::task etcd::Client::watch(std::string const & key, std::string const & range_end) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.range_end.assign(range_end); params.withPrefix = false; @@ -771,7 +822,7 @@ pplx::task etcd::Client::watch(std::string const & key, std::str pplx::task etcd::Client::watch(std::string const & key, std::string const & range_end, int64_t fromIndex) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key.assign(key); params.range_end.assign(range_end); params.withPrefix = false; @@ -787,7 +838,7 @@ pplx::task etcd::Client::leasegrant(int ttl) // immediately after the lease is granted by the server. return Response::create([this, ttl]() { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.ttl = ttl; params.lease_stub = stubs->leaseServiceStub.get(); return std::make_shared(params); @@ -798,7 +849,7 @@ pplx::task> etcd::Client::leasekeepalive(int tt return pplx::task>([this, ttl]() { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.ttl = ttl; params.lease_stub = stubs->leaseServiceStub.get(); auto call = std::make_shared(params); @@ -812,7 +863,7 @@ pplx::task> etcd::Client::leasekeepalive(int tt pplx::task etcd::Client::leaserevoke(int64_t lease_id) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.lease_id = lease_id; params.lease_stub = stubs->leaseServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncLeaseRevokeAction(params)); @@ -822,7 +873,7 @@ pplx::task etcd::Client::leaserevoke(int64_t lease_id) pplx::task etcd::Client::leasetimetolive(int64_t lease_id) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.lease_id = lease_id; params.lease_stub = stubs->leaseServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncLeaseTimeToLiveAction(params)); @@ -849,7 +900,7 @@ pplx::task etcd::Client::lock(std::string const &key, int lease_ } etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key = key; params.lease_id = lease_id; params.lock_stub = stubs->lockServiceStub.get(); @@ -871,7 +922,7 @@ pplx::task etcd::Client::lock(std::string const &key, int lease_ pplx::task etcd::Client::lock_with_lease(std::string const &key, int64_t lease_id) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key = key; params.lease_id = lease_id; params.lock_stub = stubs->lockServiceStub.get(); @@ -882,7 +933,7 @@ pplx::task etcd::Client::lock_with_lease(std::string const &key, pplx::task etcd::Client::unlock(std::string const &lock_key) { // issue a "unlock" request etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.key = lock_key; params.lock_stub = stubs->lockServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncUnlockAction(params)); @@ -914,7 +965,7 @@ pplx::task etcd::Client::unlock(std::string const &lock_key) { pplx::task etcd::Client::txn(etcdv3::Transaction const &txn) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.kv_stub = stubs->kvServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncTxnAction(params, txn)); return Response::create(call); @@ -923,7 +974,7 @@ pplx::task etcd::Client::txn(etcdv3::Transaction const &txn) { pplx::task etcd::Client::campaign( std::string const &name, int64_t lease_id, std::string const &value) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.name = name; params.lease_id = lease_id; params.value = value; @@ -936,7 +987,7 @@ pplx::task etcd::Client::proclaim( std::string const &name, int64_t lease_id, std::string const &key, int64_t revision, std::string const &value) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.name = name; params.lease_id = lease_id; params.key = key; @@ -949,7 +1000,7 @@ pplx::task etcd::Client::proclaim( pplx::task etcd::Client::leader(std::string const &name) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.name = name; params.election_stub = stubs->electionServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncLeaderAction(params)); @@ -959,7 +1010,7 @@ pplx::task etcd::Client::leader(std::string const &name) { std::unique_ptr etcd::Client::observe( std::string const &name, const bool once) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.name.assign(name); params.election_stub = stubs->electionServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncObserveAction(params, once)); @@ -972,7 +1023,7 @@ std::unique_ptr etcd::Client::observe( std::unique_ptr etcd::Client::observe( std::string const &name, std::function callback, const bool once) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.name.assign(name); params.election_stub = stubs->electionServiceStub.get(); std::shared_ptr call(new etcdv3::AsyncObserveAction(params, once)); @@ -985,7 +1036,7 @@ std::unique_ptr etcd::Client::observe( pplx::task etcd::Client::resign( std::string const &name, int64_t lease_id, std::string const &key, int64_t revision) { etcdv3::ActionParameters params; - params.auth_token.assign(this->auth_token); + params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.name = name; params.lease_id = lease_id; params.key = key; @@ -995,6 +1046,10 @@ pplx::task etcd::Client::resign( return Response::create(call); } +const std::string &etcd::Client::current_auth_token() const { + return this->token_authenticator->renew_if_expired(); +} + etcd::Client::Observer::~Observer() { if (action != nullptr) { action->CancelObserve(); diff --git a/src/KeepAlive.cpp b/src/KeepAlive.cpp index 15fb2d2..c298913 100644 --- a/src/KeepAlive.cpp +++ b/src/KeepAlive.cpp @@ -27,7 +27,7 @@ etcd::KeepAlive::KeepAlive(Client const &client, int ttl, int64_t lease_id): stubs->leaseServiceStub = Lease::NewStub(client.channel); etcdv3::ActionParameters params; - params.auth_token.assign(client.auth_token); + params.auth_token.assign(client.current_auth_token()); params.lease_id = this->lease_id; params.lease_stub = stubs->leaseServiceStub.get(); @@ -52,8 +52,8 @@ etcd::KeepAlive::KeepAlive(std::string const & address, int ttl, int64_t lease_i etcd::KeepAlive::KeepAlive(std::string const & address, std::string const & username, std::string const & password, - int ttl, int64_t lease_id): - KeepAlive(Client(address, username, password), ttl, lease_id) { + int ttl, int64_t lease_id, int const auth_token_ttl): + KeepAlive(Client(address, username, password, auth_token_ttl), ttl, lease_id) { } etcd::KeepAlive::KeepAlive(Client const &client, @@ -64,7 +64,7 @@ etcd::KeepAlive::KeepAlive(Client const &client, stubs->leaseServiceStub = Lease::NewStub(client.channel); etcdv3::ActionParameters params; - params.auth_token.assign(client.auth_token); + params.auth_token.assign(client.current_auth_token()); params.lease_id = this->lease_id; params.lease_stub = stubs->leaseServiceStub.get(); @@ -94,8 +94,8 @@ etcd::KeepAlive::KeepAlive(std::string const & address, etcd::KeepAlive::KeepAlive(std::string const & address, std::string const & username, std::string const & password, std::function const &handler, - int ttl, int64_t lease_id): - KeepAlive(Client(address, username, password), handler, ttl, lease_id) { + int ttl, int64_t lease_id, const int auth_token_ttl): + KeepAlive(Client(address, username, password, auth_token_ttl), handler, ttl, lease_id) { } etcd::KeepAlive::~KeepAlive() diff --git a/src/SyncClient.cpp b/src/SyncClient.cpp index cb28bdb..61c6dc8 100644 --- a/src/SyncClient.cpp +++ b/src/SyncClient.cpp @@ -18,8 +18,9 @@ etcd::SyncClient::SyncClient(std::string const & address, std::string const & lo etcd::SyncClient::SyncClient(std::string const & address, std::string const & username, std::string const & password, + const int auth_token_ttl, std::string const & load_balancer) - : client(address, username, password, load_balancer) + : client(address, username, password, auth_token_ttl, load_balancer) { } diff --git a/src/Watcher.cpp b/src/Watcher.cpp index 50fd291..d0dbf54 100644 --- a/src/Watcher.cpp +++ b/src/Watcher.cpp @@ -28,7 +28,7 @@ etcd::Watcher::Watcher(Client const &client, std::string const & key, int fromIn fromIndex(fromIndex), recursive(recursive) { stubs.reset(new EtcdServerStubs{}); stubs->watchServiceStub = Watch::NewStub(client.channel); - doWatch(key, "", client.auth_token, callback); + doWatch(key, "", client.current_auth_token(), callback); } etcd::Watcher::Watcher(Client const &client, std::string const & key, @@ -37,7 +37,7 @@ etcd::Watcher::Watcher(Client const &client, std::string const & key, fromIndex(fromIndex), recursive(false) { stubs.reset(new EtcdServerStubs{}); stubs->watchServiceStub = Watch::NewStub(client.channel); - doWatch(key, range_end, client.auth_token, callback); + doWatch(key, range_end, client.current_auth_token(), callback); } etcd::Watcher::Watcher(std::string const & address, std::string const & key, @@ -65,29 +65,33 @@ etcd::Watcher::Watcher(std::string const & address, std::string const & key, etcd::Watcher::Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, - std::function callback, bool recursive): - Watcher(address, username, password, key, -1, callback, recursive) { + std::function callback, bool recursive, + int const auth_token_ttl): + Watcher(address, username, password, key, -1, callback, recursive, auth_token_ttl) { } etcd::Watcher::Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, std::string const & range_end, - std::function callback): - Watcher(address, username, password, key, range_end, -1, callback) { + std::function callback, + int const auth_token_ttl): + Watcher(address, username, password, key, range_end, -1, callback, auth_token_ttl) { } etcd::Watcher::Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, int fromIndex, - std::function callback, bool recursive): - Watcher(Client(address, username, password), key, fromIndex, callback, recursive) { + std::function callback, bool recursive, + int const auth_token_ttl): + Watcher(Client(address, username, password, auth_token_ttl), key, fromIndex, callback, recursive) { } etcd::Watcher::Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, std::string const & range_end, int fromIndex, - std::function callback): - Watcher(Client(address, username, password), key, range_end, fromIndex, callback) { + std::function callback, + int const auth_token_ttl): + Watcher(Client(address, username, password, auth_token_ttl), key, range_end, fromIndex, callback) { } etcd::Watcher::~Watcher() diff --git a/tst/CMakeLists.txt b/tst/CMakeLists.txt index 820b561..ecae58f 100644 --- a/tst/CMakeLists.txt +++ b/tst/CMakeLists.txt @@ -5,6 +5,9 @@ add_custom_target(check ${CMAKE_COMMAND} -E env CTEST_OUTPUT_ON_FAILURE=1 ${CMAKE_CTEST_COMMAND} -C $ --verbose WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) +add_custom_target(etcd_tests) +add_dependencies(check etcd_tests) + file(GLOB TEST_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") foreach(testfile ${TEST_FILES}) string(REGEX MATCH "^(.*)\\.[^.]*$" dummy ${testfile}) @@ -21,5 +24,5 @@ foreach(testfile ${TEST_FILES}) target_include_directories(${test_name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../proto/gen/proto) target_link_libraries(${test_name} etcd-cpp-api) - add_dependencies(check ${test_name}) + add_dependencies(etcd_tests ${test_name}) endforeach()