Skip to content

Commit

Permalink
[Configs] Fix config env overrides
Browse files Browse the repository at this point in the history
Given that `list_separator` is called, the `config` crate expects every key to be a list unless `with_list_parse_key` is called which defines the list of keys that are supposed to be vectors. This diff lets each service define which of its keys are vector and pass it during service config registration.
  • Loading branch information
MohamedBassem committed Jul 31, 2023
1 parent 17ec962 commit 5f334d8
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
19 changes: 12 additions & 7 deletions cronback-lib/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ pub struct ConfigBuilder {
builder: InnerBuilder<DefaultState>,
file_sources: Vec<PathBuf>,
section_loaders: SectionLoaders,
array_keys: HashSet<String>,
}

impl ConfigBuilder {
Expand All @@ -78,6 +79,7 @@ impl ConfigBuilder {
builder,
file_sources: Vec::default(),
section_loaders: HashMap::default(),
array_keys: HashSet::default(),
};
// Register main section loader by default.
loader = loader.register_section_loader::<MainConfig>("main");
Expand All @@ -104,10 +106,11 @@ impl ConfigBuilder {
}
}

pub fn register_service<S>(self) -> Self
pub fn register_service<S>(mut self) -> Self
where
S: CronbackService,
{
self.array_keys.extend(S::config_vec_keys());
self.add_default_toml(S::DEFAULT_CONFIG_TOML)
.register_section_loader::<<S as CronbackService>::ServiceConfig>(
S::CONFIG_SECTION,
Expand All @@ -117,12 +120,14 @@ impl ConfigBuilder {
// This needs to be the last source added to the builder to ensure that
// environemnt variables are not overridden by files or default config.
fn add_env_source(mut self) -> Self {
self.builder = self.builder.add_source(
Environment::with_prefix(&self.env_prefix)
.try_parsing(true)
.separator("__")
.list_separator(","),
);
let mut env = Environment::with_prefix(&self.env_prefix)
.try_parsing(true)
.separator("__")
.list_separator(",");
for key in &self.array_keys {
env = env.with_list_parse_key(key);
}
self.builder = self.builder.add_source(env);
self
}

Expand Down
7 changes: 7 additions & 0 deletions cronback-lib/service.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashSet;
use std::convert::Infallible;
use std::error::Error;
use std::net::SocketAddr;
Expand Down Expand Up @@ -59,6 +60,12 @@ pub trait CronbackService: Send + Sync + Sized + Clone + 'static {
ServiceContext::new(config, shutdown)
}

// The list of keys in this service configs that should be parsed
// as vectors.
fn config_vec_keys() -> HashSet<String> {
HashSet::default()
}

/// Optional hook to install telemetry for the service.
fn install_telemetry() {}

Expand Down
7 changes: 7 additions & 0 deletions cronback-services/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod logging;
mod migration;
mod paginated;

use std::collections::HashSet;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Instant;
Expand Down Expand Up @@ -73,6 +74,12 @@ impl CronbackService for ApiService {
);
}

fn config_vec_keys() -> HashSet<String> {
let mut set = HashSet::new();
set.insert("api.admin_api_keys".to_string());
set
}

#[tracing::instrument(skip_all, fields(service = context.service_name()))]
async fn serve(
mut context: ServiceContext<Self>,
Expand Down

0 comments on commit 5f334d8

Please sign in to comment.