use std::time::Duration;
use dynamic_config::{dynamic_config, Format, RemoteSource};
use dynamic_config_git::{Credential, GitSource, Keys, TlsConfig};
use serde::Deserialize;
#[dynamic_config]
#[derive(Debug, Deserialize)]
struct AppConfig {
db: Db,
server: Server,
}
#[derive(Debug, Deserialize)]
struct Db {
host: String,
port: u16,
}
#[derive(Debug, Deserialize)]
struct Server {
port: u16,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = std::env::var("GIT_URL").unwrap_or_else(|_| "file:///tmp/config-repo".to_owned());
let credential = match std::env::var("GIT_TOKEN") {
Ok(token) => Credential::token(token),
Err(_) => Credential::anonymous(),
};
let mut source = GitSource::builder(&url)
.branch("main")
.path(Keys::prefix("conf"))
.format(Format::Yaml)
.credential(credential)
.with_timeout(Duration::from_secs(30));
if url.starts_with("https://") {
if let Ok(bundle) = std::env::var("GIT_CA_BUNDLE") {
let mut tls = TlsConfig::new()
.with_ca_certificate_file(bundle);
if let (Ok(certificate), Ok(key)) = (
std::env::var("GIT_CLIENT_CERT"),
std::env::var("GIT_CLIENT_KEY"),
) {
tls = tls.with_client_certificate_files(certificate, key);
}
source = source.tls(tls);
}
}
let source = source.build()?;
println!("reading {}", source.describe());
AppConfig::set_remote(source);
AppConfig::refresh_remote()?;
AppConfig::builder("app").env("APP_").init()?;
let current = AppConfig::current();
println!(
"database {}:{}, server on {}",
current.db.host, current.db.port, current.server.port
);
Ok(())
}