use dynamic_config::{dynamic_config, AsyncRemoteSource};
use dynamic_config_etcd::{ConnectOptions, Etcd, TlsConfig};
use serde::Deserialize;
#[dynamic_config]
#[derive(Debug, Deserialize)]
struct DbConfig {
host: String,
port: u16,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let endpoint =
std::env::var("ETCD_ENDPOINT").unwrap_or_else(|_| "http://127.0.0.1:2379".to_owned());
let options = ConnectOptions::new();
let mut tls = TlsConfig::new();
if let Ok(ca) = std::env::var("ETCD_CA") {
println!("trusting the authority in {ca}");
tls = tls.with_ca_certificate_file(ca);
}
match (
std::env::var("ETCD_CLIENT_CERT"),
std::env::var("ETCD_CLIENT_KEY"),
) {
(Ok(certificate), Ok(key)) => {
println!("presenting the client certificate in {certificate}");
tls = tls.with_client_certificate_files(certificate, key);
}
_ => println!(
"ETCD_CLIENT_CERT and ETCD_CLIENT_KEY are not both set, so no \
client certificate is presented."
),
}
println!("tls = {tls:?}\n");
let source = if tls.is_empty() {
Etcd::with_options([endpoint.as_str()], "myapp/db.json", options).await?
} else {
Etcd::with_tls([endpoint.as_str()], "myapp/db.json", options, &tls).await?
};
println!("built a source for {}\n", source.describe());
DbConfig::set_remote_async(source);
DbConfig::refresh_remote_async().await?;
DbConfig::builder("db").init()?;
let config = DbConfig::current();
println!("host = {}", config.host);
println!("port = {}", config.port);
Ok(())
}