Expand description
Read dynamic-config configuration from Consul’s key/value store.
Consul’s KV API is plain HTTP, so this implements the blocking
RemoteSource trait: nothing here needs an async runtime, and neither
does using it.
use dynamic_config_consul::Consul;
DbConfig::set_remote(
Consul::new("http://consul.internal:8500", "myapp/db.json")
.with_token(std::env::var("CONSUL_HTTP_TOKEN")?),
);
DbConfig::refresh_remote()?;§What it reads
GET {address}/v1/kv/{key}, and base64-decodes the single Value Consul
returns. The stored value is a whole configuration document — the same
bytes that would be in a config file — so the format comes from the key’s
extension, or from with_format.
That is the opposite of dynamic-config-vault, which wraps a secret’s
fields under a section key. The difference is not a whim: Vault stores a map
of named secrets, Consul stores an opaque blob, and each is easiest to use
as what it already is.
§Watching
Consul cannot push, but it can hold a request open until something changes —
a blocking query. Consul::watch is that loop, and it is genuinely
change-driven rather than a poll with extra steps: the agent answers the
moment the key moves.
It blocks, so it belongs on a thread, and a thread cannot be cancelled from
outside — hence the Watching token.
let watch = RemoteWatch::new();
let watching = watch.watching();
std::thread::spawn(move || consul.watch(&watching, DbConfig::apply_remote));
// Dropping `watch` — or calling `watch.stop()` — ends the loop.Re-exports§
Modules§
- auth
- Getting an ACL token, and getting another one when it stops working.
Structs§
- Consul
- A key in Consul’s KV store, as a configuration source.